java static initialization with inheritance

    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.");
        }
    }

Question: Why output will be: "x". But not: "Inside Bx"


The reference to Bx issues the following bytecode:

getstatic       #3   <Field int B.x>

According to Java Virtual Machine Spec

The Java virtual machine instructions anewarray, checkcast, getfield, getstatic , instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, multianewarray, new, putfield, and putstatic make symbolic references to the runtime constant pool. Execution of any of these instructions requires resolution of its symbolic reference .

So the JVM should resolve the symbolic reference to Bx . The field resolution is specified like this:

To resolve an unresolved symbolic reference from D to a field in a class or interface C, the symbolic reference to C given by the field reference must first be resolved (§5.4.3.1).

...

When resolving a field reference, field resolution first attempts to look up the referenced field in C and its superclasses :

If C declares a field with the name and descriptor specified by the field reference, field lookup succeeds. The declared field is the result of the field lookup.

Otherwise, field lookup is applied recursively to the direct superinterfaces of the specified class or interface C.

Otherwise, if C has a superclass S, field lookup is applied recursively to S.

Otherwise, field lookup fails.

In other words the JVM will resolve Bx into Ax . This is why only A class needs to be loaded.


因为Bx实际上是Ax所以只需要加载A类。


§12.4 "Initialization of Classes and Interfaces" of The Java Language Specification, Java SE 7 Edition specifies that:

Initialization of a class consists of executing its static initializers and the initializers for static fields (class variables) declared in the class.

[…]

A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

So although — contrary to claims in some of the answers above — class B does have to be loaded, in order to determine that Bx is declared in A , class B is not initialized (ie, its static initializers are not actually run) until you do something more specific to B .

链接地址: http://www.djcxy.com/p/3478.html

上一篇: 为什么使用随机字符串的代码打印出“hello world”?

下一篇: java继承的静态初始化