继承中的静态方法

Static method in inheritance

class A
{
    static{
        get();
    }
    static void get(){
        System.out.println("HELLO");
    }
}

class B extends A
{
    public static void main(String[] args) {

    }
}

输出:

HELLO

如何调用 class A 的静态方法。我可以理解 B 的静态方法被调用但不理解 A.

因为,由于B继承了ABmain()执行时,必须加载A。这将激活 get() 函数,因为它位于静态块中。

因为 B 从 A 扩展,如果 B class 被加载,那么 A class 必须被加载,如果它被加载,它的静态初始化块必须被调用。

在继承中 class 加载是从上到下发生的,即父到子。 它首先在您的案例 A 中加载父项 class,然后在您的案例 B 中加载子项 class。当 class 加载它的静态块时首先被调用,这就是为什么它的打印 HELLO

在编译期间,编译器知道 B 依赖于 A。它将相同的数据传递给 JVM。在class B的加载阶段,JVM读取编译器发送的元数据,发现B依赖于A,因此加载(和 A 的 运行s 静态初始化程序)然后继续加载 B 然后初始化 B

如果我们有 2 classes SampleTest extends Sample,Class 常量池(字节码的一部分)对于 Test 将有:

Constant pool:
   #1 = Class              #2             //  Test
   #2 = Utf8               Test
   #3 = Class              #4             //  Sample <---- reference
   #4 = Utf8               Sample
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          //  Sample."<init>":()V   <-- init Sample
   #9 = NameAndType        #5:#6          //  "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               LTest;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               SourceFile
  #19 = Utf8               Sample.java

如果你 运行 java 使用 verbose:class 选项然后 grep 它,你将能够看到 dependant class 正在加载。

java -verbose:class Test | grep 'Sample'

[Loaded Sample from file:/Users/XXXX/Workspaces/SampleTest/Sample/bin/] <== Sample loaded first because test depends on Sample.
[Loaded Test from file:/Users/XXXX/Workspaces/SampleTest/Sample/bin/]

要执行classB的main方法,必须加载classB。

Class B extends class A,所以要加载B,必须加载class A。

当 class A 被加载时,它的静态初始化器被调用,调用 get() 方法并打印 "HELLO".

所有静态块都在 class 加载时执行...重复问题 When is the static block of a class executed?