1.static的使用
1.在本类中:
1.static可以修饰属性和方法,但不能修饰构造方法和外部类(内部类可以修饰)
2.在本类中静态方法可以直接调用静态属性和静态方法,因为它在类装载器中已经开辟好了内存
3.在本类中静态方法不可以直接调用非静态方法和非静态属性如果想要调用就必须要new对象,通过对象名.方法名或对象名.属性名调用,因为非静态方法和非静态属性在new对象的时候才开辟内存
4.在本类中非静态方法可以直接调用静态属性和静态方法,非静态方法也可以直接调用非静态属性和非静态方法
2.在非本类中:
1.在调非本类中的静态方法和静态属性可以通过类名.方法名或类名.属性名直接调用。也可以用对象.访问
2.在调非本类中的非静态方法和非静态属性不可以直接通过类名.方法名或类名.属性名直接调用,调用之前必须new对象
3.在调非本类中的非静态方法和非静态属性之前必须new对象,在通过对象名.方法名或对象名.属性名调用
3.其它:
1.类中的静态方法,静态属性内存只分配一次,在类装载器中完成
2.static修饰的属性属于类而不属于某个对象(static修饰的属性,不管类中new多少个对象,static属性是所有对象共用的)
public class Demo {
public static void main(String[] args) {
A one=new A();
System.out.println(one.velue);
System.out.println(one.sum);
A two=new A();
System.out.println(two.velue);
System.out.println(two.sum);
//改变one中的静态属性
one.velue=99;
System.out.println("改变one中value后,one中value的值:"+one.velue);//99
System.out.println("改变one中value后,two中value的值:"+two.velue);//99
//改变one中的非静态属性
one.sum=88;
System.out.println("改变one中sum后,one中sum的值:"+one.sum);//88
System.out.println("改变one中sum后,two中sum的值:"+two.sum);//20
}
}
class A{
static int velue=10;
int sum=20;
}
3.static修饰的方法中不能以任何的形式访问this和super
4.main方法是程序的入口,必须用 static修饰
5.如果想第一时间执行加载的代码可以放在静态代码块中执行,不管调用这个类多少次,静态代码块只执行一次
6.注意:static不能修饰局部变量,意思就是不能在方法里用static修饰方法里的变量
3.案例:
public class Main {
static int value=10;
int num=20;
public static void fun() {
System.out.println("静态方法fun");
}
public static void funTwo() {
System.out.println("静态方法funTwo");
}
public void funThree() {
System.out.println("非静态方法funThree");
fun();//在本类中非静态方法可以直接调静态方法和静态属性
funTwo();
System.out.println(value);
funFour();//在 本类中非静态方法可以直接调非静态方法和非静态属性
System.out.println(num);
}
public void funFour() {
System.out.println("非静态方法funFour");
}
/*public static Main(){static不可以修饰构造方法
}*/
public static void main(String[] args) {
fun();//在本类中静态方法可以直接调用静态方法和静态属性,因为它在类装载器中已经开辟好了内存
funTwo();
System.out.println(value);
/*funThree();在本类中静态方法不可直接调用非静态方法和非静态属性,如果想要调用就必须要new对象,因为非静态方法和非静态属性在new对象的时候才开辟内存
funFour();
System.out.println(num);*/
Main ma=new Main();
ma.funThree();
Test.method();//在调非本类中的静态方法和静态属性可以通过类名.方法名或类名.属性名直接调用
System.out.println(Test.test1);
/*Test.methodTwo();在调非本类中的非静态方法和非静态属性不可直接通过类名.方法名或类名.属性名直接调用 ,调用之前必须new对象
System.out.println(Test.test2);*/
Test t=new Test();
t.methodTwo();//在调非本类中的非静态方法和非静态属性必须先new对象,在通过对象名.方法名或对象名.属性名调用
System.out.println(t.test2);
}
/*
* public static class Test {//static不能修饰外部类
}
*/
public class Test {
/*public static class Test2{static可以修饰内部类
}*/
static int test1=111;
int test2=222;
public static void method() {
System.out.println("静态方法method");
}
public void methodTwo() {
System.out.println("非静态方法methodTwo");
}
}
2.代码块
代码块种类:静态代码块,构造代码块,普通代码块,同步代码块
1.静态代码块
static{
}
静态代码块在类被加载的时候就运行了,而且只执行一次,不管new多少对象
在一个类里,静态代码块可以有多个,并依次执行
静态代码块优于其它代码先运行
静态代码块里不可以访问非静态的东西
static{
//add();报错,因为静态的内容已经被类装载器加载到内存里了,而非静态这时候还没有被装载到内存里,所以已经在内存里的东西去访问还不在内存里的东西就会报错
}
public void add(){
}
静态代码块不能存在任何方法体中
public static void add(){
/*static {报错
}*/
}
2.构造代码块
{
System.out.println("构造代码块");
}
构造代码块在创建对象时被调用,每次创建对象都会调用一次,但是优于构造函数执行。
一个类里可以有多个构造代码块
class Temp{
{
System.out.println("构造1");
}
{
System.out.println("构造2");
}
{
System.out.println("构造3");
}
}
public void test1(){
new Temp();
new Temp();
}
3.普通代码块
普通代码块和构造代码块的区别是,构造代码块是在类中定义的,而普通代码块是在方法中定义的
public void sayHello(){
{
System.out.println("普通代码块");
}
}
3.类里面的成员初始化顺序:
静态代码块–》静态成员(属性和方法)–》非静态成员(属性和方法)–》构造方法