java - 为什么子类的静态代码会被执行?

标签 java constructor static static-methods

我已经编写了以下代码并为父类(super 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

我知道只有在初始化类的对象或进行任何静态引用时才会执行静态 block 。但是在这里,我没有对 Sub 类做任何这些。那为什么我会看到“子”,即子类的静态 block 输出?

最佳答案

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. 的加载
  3. JVM 必须加载 SuperClass 才能加载 Sub

  4. 所以我们看到它们的静态初始化程序按顺序运行(SuperClass,然后是 Sub):

    super
    sub
    
  5. java 工具调用main

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

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

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

    2
    

作为 Holger乐于助人points out ,这在 §5.5 - Initialization 中的 JVM 规范中涵盖。和相关的§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

关于java - 为什么子类的静态代码会被执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35150847/

相关文章:

c# - 如何在 .net 中使用 C# 对默认构造函数类进行单元测试?

rust - "statics cannot evaluate destructors"在 Rust

python - 包括 SimpleHTTPServer?

java - 更新Map的Map值

java - 剪刀石头布游戏 3 中最佳 2 循环问题

javascript - 使用构造函数帮助填充 Raphael 和 joint.js 功能

c++ - 如何调用 std::vector 中包含的对象的构造函数?

c++ - 复杂类型数组的静态初始化

java - 在函数内部或外部声明对象

java - 使用预签名 URL 从 S3 下载对象