【问题标题】:Execution of child class' static block derived from abstract class执行从抽象类派生的子类的静态块
【发布时间】:2018-12-18 07:01:36
【问题描述】:
public class Test15 {
    public static void main(String[] args) {
        System.out.println(B.x);
    }
}

abstract class A { 
    static int x=99;

    A() {
        System.out.println("A DC");
    }

    static {
        System.out.println("A SB");
    }
}

class B extends A {
    static {
        System.out.println("B Sb");
    }
}

为什么在上面的程序中子类的静态块没有被执行?

【问题讨论】:

  • 这个访问确实应该是编译器警告。

标签: java class abstract


【解决方案1】:

x 是类Astatic 变量,因此即使您通过B.x 访问它,也无需初始化类B。因此,B 类的 static 初始化程序不会被执行。

这是相关的JLS 12.4.1 quote

对静态字段的引用(第 8.3.1.1 节)只会初始化实际声明它的类或接口,即使它可能通过子类、子接口或实现的类的名称来引用一个界面。

【讨论】:

  • 但是 B 类呢。它是否已加载?
  • @ANSHULKUMAR 我相信 B 已加载,基于 Resolution is the process of checking symbolic references from Test to other classes and interfaces, by loading the other classes and interfaces that are mentioned and checking that the references are correctTest 是具有正在执行的 main 方法的类)。
  • @ANSHULKUMAR 不过,进一步阅读,无论是否加载 B,这可能是一个实现细节 - An implementation may instead choose to resolve a symbolic reference only when it is actively used; consistent use of this strategy for all symbolic references would represent the "laziest" form of resolution. In this case, if Test had several symbolic references to another class, then the references might be resolved one at a time, as they are used, or perhaps not at all, if these references were never used during execution of the program.
  • @ANSHULKUMAR 说,我很确定 B 必须加载。如果不加载类B,我们无法知道B.x 不是类B 的成员。
  • @chrylis 是的,尽管 OP 的问题是关于类初始化,而不是加载。加载只在 cmets 中提及。
【解决方案2】:

B 的静态块只会在 B 类初始化时执行。调用其超类A 的字段x 不会导致类B 被初始化。

来自 Java 规范:

12.4.1 初始化发生时

类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:

• T 是一个类,并创建了一个 T 的实例。

• T 是一个类,并且调用了 T 声明的静态方法。

• 分配了一个由 T 声明的静态字段。

• 使用了由 T 声明的静态字段,并且该字段不是常量变量(第 4.12.4 节)。

• T 是一个顶级类(第 7.6 节),并且执行在词法上嵌套在 T(第 8.1.3 节)中的断言语句(第 14.10 节)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 2011-02-01
    • 2013-12-30
    • 1970-01-01
    • 2010-10-08
    • 2019-03-12
    • 1970-01-01
    相关资源
    最近更新 更多