被static修饰的变量、方法统一属于类的 静态资源,被同一个类的所有对象共享,他们都有访问和修改的权限。 可以通过 类名.变量名/方法名 直接获取。
从JVM的类加载机制的角度讲,静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的,因此静态资源比非静态资源先出现,所以有下面三个结论:
- 静态方法不能引用非静态资源
- 静态方法里面可以引用静态资源
- 非静态方法里面可以引用静态资源
静态代码块
和静态变量、静态方法一样,静态块里面的代码只执行一次,且只在初始化类的时候执行。
public class A {
private static int a = B();
static {
System.out.println("Enter A.static block");
}
public static void main(String[] args) {
new A();
}
public static int B() {
System.out.println("Enter A.B()");
return 1;
}
}
打印结果是:
Enter A.B()
Enter A.static block
得出第一个结论:静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。
另外还有优先级的结论:静态块先于main函数执行,毕竟静态块在类执行前就运行完了。
静态代码块与构造块的执行顺序:父类优先,静态优先,构造最后
父类静态块 -> 子类静态块 -> 父类非静态代码块 -> 父类构造函数 -> 子类非静态代码块 -> 子类构造函数
再看一个例子:
1 public class A
2 {
3 static
4 {
5 c = 3;
6 System.out.println(c);
7 }
8
9 private static int c;
10 }
这段代码第5行不报错,但第6行是有错误的:Cannot reference a field before it is defined。从这个例子得出第三个结论:静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问。