java - java中类层次结构中的类是如何初始化的?

标签 java inheritance

调试子表达式

Sub.x

在表达式中

System.out.println(Sub.x);

在下面给出的代码中,了解 JVM 内存空间中的类(即 class Subclass Super)在运行时初始化的规则。

package defaultvalues;
import java.util.*;

class Super{
    static int x;
    static{
        System.out.println("Super");
    }
}

class Sub extends Super{
    Date date;
    {//instance initialisation block for date
        Calendar temp = Calendar.getInstance();
        date = temp.getTime();
    }
    static{
        System.out.println("Sub");
    }

    long alarm;
}

class Game{
    static Random rand;
    static{
        rand = new Random();
    }
    static void tossCoin(){
        if(rand.nextBoolean()){
            System.out.println("Heads");
        }else{
            System.out.println("Tails");
        }
    }

}
public class Example {
    public static void main(String[] args) {
        System.out.println(Sub.x); // class Super is loaded. From class Super, static members are
        //initialised and static initialisation blocks are executed before executing expression 'Sub.x'

        Game.tossCoin(); // class Game is loaded. From class Game, static members are initialised
        //and static initialiser blocks are executed before executing expression 'Game.tossCoin()'
        Sub obj = new Sub(); //instance variables are initialised and instance initialisation block 
        //of class A are executed.
        System.out.println(obj.date);
        System.out.println(obj.alarm);
    }

}

调试后,观察到,在表达式 Sub.x 求值之前,class Super 已初始化,但 class Sub 并未初始化。计算表达式 System.out.println(Sub.x); 后的立即输出是:

Super
0

因此,System.out.println("Sub"); 在表达式 Sub.x 求值之前不会执行。

关于此表达式 Sub.x 求值,在源代码中,我看到表达式 Sub.x 正在求值,class Super已初始化,但 class Sub 未初始化。

我的问题是:

在运行时评估子表达式 Sub.x 之前,class Sub 是否已加载并链接但未初始化?

注意:在 Eclipse 环境中工作

最佳答案

您描述的行为在 JLS 的示例中给出,here

Example 12.4.1-2. Only The Class That Declares static Field Is Initialized

class Super {
    static int taxi = 1729;
}
class Sub extends Super {
    static { System.out.print("Sub "); }
}
class Test {
    public static void main(String[] args) {
        System.out.println(Sub.taxi);
    }
}

This program prints only:

1729

because the class Sub is never initialized; the reference to Sub.taxi is a reference to a field actually declared in class Super and does not trigger initialization of the class Sub.

与初始化原因列表匹配

  • A static field declared by T is used and the field is not a constant variable (§4.12.4).

该字段由 Super 声明,而不是 Sub

关于java - java中类层次结构中的类是如何初始化的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30872441/

相关文章:

java - 动态方法调用(继承中的对象和引用)

C++:覆盖公共(public)\私有(private)继承

java - 为什么默认弃用的 java.net.URLEncoder.encode 有效,但在我指定字符集时却无效?

java - 如何在 Java 中表示位字段(并发送它们)

java.lang.AssertionError : Status 404

grails - Grails/GORM 中的继承和约束问题

c# - 抽象类类型C#的调用子实现

java - 如何使组件中的 mouseEvent 在子组件中被识别?

java - Json 多态性与 Jackson 和 Json 没有包装对象

c - 面向对象的C : Building vtables