为什么要执行 sub class' 静态代码?

Why is sub class' static code getting executed?

我已经编写了以下代码并为超级 class 创建了对象。

class SuperClass{
    static int a=2;
    static int b(){
        return 2;
    }
    int c(){
        return 2;
    }

    SuperClass(){
        System.out.println("Super");
    }
    static {
        System.out.println("super");
    }
}

public class Sub extends SuperClass{
    Sub(){
    System.out.println("Sub");
    }
    static {
        System.out.println("sub");
    } 
    static int b(){
        return 3;
    }
    int c(){
        return 3;
    }
    public static void main(String ax[]){
        SuperClass f =new SuperClass();
        System.out.println(f.c());
        System.out.print(SuperClass.b());
    }   
}

我查看输出结果如下:

super
sub
Super
2
2

我知道只有当 class 的对象被初始化或任何静态引用被创建时,静态块才会被执行。但是在这里,我没有对 Sub class 做任何这些。那为什么我看到 "sub" 即 sub class' 静态块输出?

因为您的 main() 方法是 Sub 的成员,所以需要为您的程序加载 class 到 运行。

I know that static block is executed only when object of the class is initialized or any static reference is made. But here, i did not make any of these to Sub class.

您的 代码没有,但为了从 main 到 运行,必须加载 Sub。所以它的静态初始值设定项是 运行.

例如,我假设你 运行 它是这样的:

java Sub

java 工具必须加载 Sub 才能调用 Sub.main。那是导致静态初始化程序为 运行 的静态引用(实际上是访问)。 (如果你 运行 它在 IDE 中, IDE 会做 java 工具部分,但结果是一样的。)

事情是这样的:

  1. java 触发加载 Sub

  2. JVM 必须加载 SuperClass 才能加载 Sub

  3. 所以我们看到它们的静态初始值设定项 运行,顺序是 (SuperClass,然后是 Sub):

    super
    sub
    
  4. java 工具调用 main

  5. main 中的代码调用 new SuperClass:

    Super
    
  6. main 中的代码调用 f.c()

    2
    
  7. main 中的代码调用 SuperClass.b:

    2
    

Holger helpfully , this is covered by the JVM specification in §5.5 - Initialization and the related §5.2 - Java Virtual Machine Startup:

Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).

A class or interface C may be initialized only as a result of:

  • ...

  • If C is a class, the initialization of one of its subclasses.

  • If C is a class, its designation as the initial class at Java Virtual Machine startup (§5.2).

倒数第二个要点涵盖 SuperClass,最后一个要点涵盖 Sub

在调用 main 时,所有的静态初始化程序都会被调用,首先在超级 class 中,然后是子 class.

这解释了您观察到的输出。

加载 class 时,静态块为 运行。通常那是因为您调用了构造函数或静态成员。在这种情况下,这是因为您执行了 main 方法(静态成员)。

旁注:

  1. 另一个极端情况正在调用 Class.forName(className) 来加载 class.
  2. 您可能还注意到基础 class 在子 class 之前加载。