面试_java_static关键字

98 阅读2分钟

被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。从这个例子得出第三个结论:静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问