我已经编写了以下代码,并为这个超类创建了对象。
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类的静态块输出?
在调用main
时,将首先在超类中调用所有静态初始化器,然后在子类中调用。
这就解释了你观察到的结果。
由于main()
方法是Sub
的成员,因此需要加载该类才能运行程序。
我知道只有在初始化类的对象或进行任何静态引用时,才会执行静态块。但在这里,我并没有把这些都带到课堂上。
您的代码没有,但为了运行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中,当您将声明为时,就是说它是类的成员,而不是对象(因此为什么只有一个)。因此,在对象上访问它是没