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

类初始化的澄清

太叔航
2023-03-14

类初始化规则规定:如果由于访问静态字段而触发类初始化,则只初始化声明了静态字段的类,即使静态字段被子类、子接口的类型或接口的实现类引用,也不会触发超类或子类的初始化。然后在下面的代码中,只应打印“初始化超类”。

Superclass.java :

public class Superclass {

    public static long INIT_TIME = System.currentTimeMillis();

    static {
        System.out.println("Initializing Superclass");
    }
}

Subclass.java:

public class Subclass extends Superclass {

    static {
        System.out.println("Initializing Subclass");
    }
}

public static void main(String[] args) {

    long time = Subclass.INIT_TIME;         
}   

}

当我运行这个时,输出:

Initializing Superclass
Initializing Subclass

共有3个答案

解晟睿
2023-03-14

正如你所说:-

如果由于访问静态字段而触发类初始化,则只初始化声明了静态字段的类,即使静态字段被子类类型、子接口或接口的实现类引用,也不会触发超类或子类的初始化

这清楚地说明输出应该是初始化超类仅限。

我运行了你的程序,得到了输出结果

初始化超类

1414998665110

如果你像你提到的那样得到输出,还有一些其他的事情你没有在你的问题中说明。

注:-参考乔恩·斯基特对这个问题的回答,似乎有一部分是错误的,它说:-

如果由于访问静态字段而触发类初始化,则只初始化声明了静态字段的类,而不会触发超级类的初始化

这与您的情况无关,因为INIT_TIMESuperclass的一部分,因此您基本上是在编写Superclass_对象。初始化时间当你说子类时。初始时间。如果在子类中有INIT_TIME字段,而不是超类,则会得到以下输出:-

初始化超类

初始化子类

1414998665110

总而言之,这意味着即使由于访问静态字段而触发了类初始化,超类也会被初始化,但子类并没有初始化

傅奕
2023-03-14

您的代码很可能是这样的:

public class Temp extends SuperTemp {  // subclass

    static {
        System.out.println("Initializing Temp");
    }

}

class SuperTemp {        // super class
    static int i = 0;
    static {
        System.out.println("Initializing SuperTemp");
    }

}

class SomeOtherClass {  

    public static void main(String[] args) {

        System.out.println(Temp.i); // from some other class you are calling SubClass.superClassField
    }
}

O/P:

Initializing SuperTemp
0

原因:在运行时Temp。i将解析为超级温度。我是JVM的。因此,Temp将被加载,但不会初始化。查看类的加载方式:

java的O/P-verbose:class

[Loaded SomeOtherClass from file XXXX]
[Loaded SuperTemp from file XXXX]
[Loaded Temp from file XXXX]
Initializing SuperTemp
0
甄煜
2023-03-14

请参阅第12.1.3章中的Java语言规范。

规则是:“如果类Test有另一个类Super作为它的超类,那么Super必须在Test之前初始化。”

子类未初始化,但超类的。

 类似资料:
  • 我找不到任何关于这个具体案例的具体SO帖子,所以我想问一下我认为是/否的问题。 以下是JLS§12.4.2(Java SE 8),清单6-7: 我的问题是:这是否意味着子类的final static变量在超类的静态初始化之前初始化(假设final static作为其声明的一部分初始化)?

  • 根据价值初始化规则。发生值初始化: 1,5)当使用由空括号或大括号组成的初始值设定项创建无名临时对象时(从C 11开始); 2,6)当一个具有动态存储持续时间的对象是由一个新表达式创建的,初始化器由一对空括号或大括号组成(从C11开始); 3,7)当使用带有空括号或大括号对的成员初始值设定项初始化非静态数据成员或基类时(自C 11起); 4)当使用由一对大括号组成的初始化程序声明命名变量(自动、静

  • 类的继承和初始化 所有类的存储属性(包括从它的父类继承的所有属性)都必须在初始化期间分配初始值 Swift为类类型定义了两种初始化器以确保所有的存储属性接收一个初始值. 这些就是所谓的指定初始化器和便捷初始化器 指定初始化器是类的主要初始化器. 指定的初始化器可以初始化所有那个类引用的属性并且条用合适的父类初始化器来继续这个初始化过程给父类链 类偏向于少量初始化器, 并且一个类通常只有一个指定初始

  • 问题内容: 我正在寻找类似于Objective-C的class方法的行为,因为该方法在类初始化时被调用一次,此后不再被调用。 一个简单的闭合将非常时尚!而且很显然,当我们在结构闭包中使用“ s”而不是“ s”时,这一切都将非常匹配! 问题答案: 如果您有一个Objective-C类,最简单的方法就是重写。但是,请确保您的类的 子 类也被覆盖,否则您的类的 子 类可能会被多次调用!如果需要,可以使用

  • 问题内容: 我正在尝试创建UIBezierPath的子类,以添加一些对我有用的属性。 编辑:我需要这个,因为在我的代码中我写 并导致编译错误: “必须调用超类’UIBezierPath’的指定初始化程序” 我试图在子类中添加该初始化器,但似乎不起作用。 你能帮我吗? 问题答案: 注意 :此问题已在iOS 9中得以解决,在该版本中,API已被重写为存在,其他所有(方便初始化程序)也是如此。 问题 简

  • 问题内容: 我最近刚与Python中的一个错误作斗争。那是那些愚蠢的新手错误之一,但是它让我思考了Python的机制(我是C ++的老程序员,是Python的新手)。我将列出错误的代码并解释如何解决该问题,然后我有两个问题。 场景:我有一个叫做A的类,它有一个字典数据成员,下面是其代码(当然这是简化的): 使用此代码的类为B类: 请注意,每次调用都会初始化类A的新“干净”实例,并在添加前后打印字典