当前位置: 首页 > 知识库问答 >
问题:

为什么要执行子类的静态代码?

史智志
2023-03-14

我已经编写了以下代码,并为这个超类创建了对象。

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

我知道只有在初始化类的对象或进行任何静态引用时,才会执行静态块。但在这里,我并没有把这些都带到课堂上。那么为什么我会看到“sub”即sub类的静态块输出?

共有3个答案

狄德泽
2023-03-14

调用main时,将首先在超类中调用所有静态初始化器,然后在子类中调用。

这就解释了你观察到的结果。

丌官飞章
2023-03-14

由于main()方法Sub的成员,因此需要加载该类才能运行程序。

仉嘉泽
2023-03-14

我知道只有在初始化类的对象或进行任何静态引用时,才会执行静态块。但在这里,我并没有把这些都带到课堂上。

您的代码没有,但为了运行main,必须加载Sub。因此,它的静态初始值设定项被运行。

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

java Sub

java工具必须加载Sub才能调用Sub.main。那是静态引用(访问,真的)导致静态初始化程序运行。(如果您在IDE中运行它,IDE将执行java工具部分,但结果是相同的。)

下面是发生的事情:

>

  • java触发Sub的加载

    JVM必须加载超类,才能加载子类

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

    super
    sub
    

    java工具调用main

    main中的代码调用new SuperClass

    Super
    

    main调用f.c()

    2
    

    main中的代码调用超类。b

    2
    

    正如霍尔格有益地指出的那样,§5.5-初始化和相关的§5.2-Java虚拟机启动中的JVM规范涵盖了这一点:

    类或接口的初始化包括执行其类或接口初始化方法(§2.9)。

    类或接口C只能在以下情况下初始化:

    >

  • 。。。

    如果C是一个类,则初始化它的一个子类。

    如果C是一个类,则其指定为虚拟机启动时Java初始类(§5.2)。

    倒数第二个要点涵盖了超类,最后一个要点涵盖了子类。

  •  类似资料:
    • 问题内容: 这是代码 我期望的输出是: 但实际上是: 看来Child类中的静态块没有得到执行,但是为什么呢?这是反直觉的,不是吗? 补充: 为了更清楚,我列出了 2 __以下 1 分: 正如@axtavt所说,根据JLS 12.4.1,类Child已加载,但未初始化。 但是@Alexei Kaigorodov指出,根据 jvms-5.5,应初始化Child类,因为对Child类执行了getstat

    • 问题内容: 我正在准备进行Java认证测试,并且发现了一个与Java静态块的执行有关的有趣问题。我已经花了很多时间阅读有关此主题的内容,但是找不到所需的答案。 我知道将类加载到JVM或调用main方法时会执行静态块,但是… 输出为: 如果我在中包含详细输出,则输出为: 我们可以在这里看到 Child类已加载 到JVM中。 有人可以解释 为什么类的静态块没有执行吗? 问题答案: 您看到该类已加载,但

    • 据我所知,init block是一个在任何构造函数之前执行的块,每当该构造函数用于创建对象时。但是为什么规则在这里矛盾...... 这里,由于只形成了子类对象,那么为什么要调用父类的init块呢?

    • 问题内容: 因此,问题或多或少是我写的。我知道可能还不清楚,所以我举一个例子。 我有Tree类,其中有Node类,并且Tree的空构造函数被编写为: Eclipse给我一个错误:空构造函数中的“ new RBTree()”没有“由于某些中间构造函数调用而导致RBTree类型的封闭实例不可用”。但是,如果将RBNode更改为静态类,则没有问题。 那么,为什么在类为静态的时候它可以工作。 顺便说一句,

    • 问题内容: 我看到了很多Java代码,其中android更愿意让开发人员使用静态内部类。特别是对于自定义ListAdapters中的ViewHolder Pattern之 类的模式。 我不确定静态类和非静态类之间的区别。我已经读过它,但是在考虑性能或内存占用时似乎没有任何意义。 问题答案: 不只是Android开发人员… 非静态内部类始终保留对封闭对象的隐式引用。如果您不需要该参考,则只需花费成本

    • 问题内容: 这是指帖子 ..无法回复或评论任何这样创建的新帖子。为什么是我的 发出警告-应该以静态方式访问静态字段MyUnits.MILLSECONDS吗?谢谢。 问题答案: 因为当您访问静态字段时,您应该在类(或本例中为枚举)上执行此操作。如 不在实例中 编辑 要解决 为什么这样 的问题:在Java中,当您将声明为时,就是说它是类的成员,而不是对象(因此为什么只有一个)。因此,在对象上访问它是没