java继承的静态初始化

Tar*_*val 17 java inheritance static static-initialization

public class Main {

    public static void main(String[] args) {
        System.out.println(B.x);
    }

}
class A {
    public static String x = "x";
}
class B extends A {
    static {
        System.out.print("Inside B.");
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:为什么输出将是:x.但不是:Inside B.x

Shy*_*hyJ 10

B.x发出以下字节码的引用:

getstatic       #3   <Field int B.x>
Run Code Online (Sandbox Code Playgroud)

根据Java虚拟机规范

Java虚拟机指示anewarray,checkcast,getfield, getstatic,instanceof,invokedynamic,invokeinterface,invokespecial,invokestatic,invokevirtual,ldc,ldc_w,multianewarray,new,putfield和putstatic 对运行时常量池进行符号引用.执行任何这些指令都需要 解析其符号引用.

所以JVM应该解析符号引用B.x.字段分辨率指定如下:

要将未解析的符号引用从D解析为类或接口C中的字段,必须首先解析由字段引用给出的对C的符号引用(第5.4.3.1节).

...

解析字段引用时,字段解析首先尝试在C及其超类中查找引用的字段:

如果C声明具有字段引用指定的名称和描述符的字段,则字段查找成功.声明的字段是字段查找的结果.

否则,字段查找以递归方式应用于指定类或接口C的直接超接口.

否则,如果C具有超类S,则将字段查找递归地应用于S.

否则,字段查找失败.

换句话说,JVM将解析B.xA.x.这就是为什么只A需要加载类.


Pet*_*rey 7

因为B.x实际上A.xA需要加载类.