static 关键字笔记
static 关键字
static 在 Java 中主要用于修饰变量、方法、代码块、类。
修饰变量和方法
被 static 修饰的变量叫做静态变量,归属于类,可以使用类名.变量名
调用。
被 static 修饰的方法叫做静态方法,归属于类,可以使用类名.方法名
调用。
关于静态方法和非静态方法的一些问题
- 静态方法能不能调用非静态资源?
- 非静态方法能不能调用静态资源?
静态资源,是在类初始化的时候加载的,而非静态资源是在类 new 的时候加载的,也就是说静态资源加载先于非静态资源。静态资源是引用不了非静态资源,因为在引用时非静态资源还没加载。非静态资源可以引用静态资源,因为那个时候资源以及全部加载完毕。
静态块
static 修饰代码块,也是初始化一个类的操作。只在初始化类的时候执行一次。静态块也有几个细节。
静态代码块的初始化顺序:
是严格按照 父类静态代码块-->子类静态代码块
这样的顺序执行的。
这里顺便说一下子类实例化的过程。
- 初始化父类静态成员变量和静态代码块。
- 初始化子类静态成员变量和静态代码块。
- 初始化父类的普通成员变量和代码块,再调用父类的构造方法
- 初始化子类的普通成员变量和代码块,再调用子类的构造方法
静态代码块和静态成员变量同时存在的情况下执行顺序。
demo:
public class Demo2_A {
private static int a = 0;
static{
a = 10;
System.out.println(a);
fun();
}
private static int b = 100;
public static void fun(){
System.out.println("b-->"+ b);
}
public static void main(String[] args) {
new Demo2_A();
}
}
执行结果:
10
b-->0
可以看,静态成员变量 a 先于静态代码块初始化,而 b 却是后于静态代码块初始化。这样就导致静态代码块可以读取到静态变量 b 的默认值,而不能读到 b 的初始化值。
如果在静态代码块中直接加入System.out.println("b-->"+ b);
,就会报错,可以赋值,但是不能访问,说 b 这个变量非法向前引用。Cannot reference a field before it is defined
错误。也就是说静态资源和静态块是按照顺序加载的,定义语句要放在静态代码块的上面。我水平有限,只能通过表面和结果分析,查看资料是说 Java编译器强制进行的一个检查
可能会有人感觉到同样是在静态代码块中,单独输出一条语句和用方法输出一条语句,单独输出就会报错,而方法调用不会。
这个还是好理解的,因为静态变量的声明在任意代码执行前发生。所以在方法中调用不存在引用出错的问题。而单独调用,因为 Java 编译器的原因不通过。后期学习 JVM 类加载过程应该就深刻了解了。