这是代码
public class ClassResolution {
static class Parent {
public static String name;
static {
System.out.println("this is Parent");
name = "Parent";
}
}
static class Child extends Parent {
static {
System.out.println("this is Child");
name = "Child";
}
}
public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Child.name);
}}
我期望的输出是:
this is Parent
this is Child
Child
但实际上是:
this is Parent
Parent
看来Child类中的静态块没有得到执行,但是为什么呢?这是反直觉的,不是吗?
补充:
为了更清楚,我列出了
2
__以下 1 分:
你怎么看?
补充2:
@Alexei Kaigorodov更新了主意,因此似乎没有分歧。但是我认为阿列克谢·凯戈罗多夫(Alexei
Kaigorodov)的观点很有启发性,所以我把它留在那里。
谢谢大家。
从JLS
12.4.1开始
:
类或接口类型T将在以下任何一种首次出现之前立即初始化:
- T是一个类,并创建T的实例。
- T是一个类,并调用T声明的静态方法。
- 分配由T声明的静态字段。
- 使用由T声明的静态字段,并且该字段不是常量变量(第4.12.4节)。
- T是一个顶级类,并执行词法嵌套在T中的assert语句(第14.10节)。
如您所见,这些都不会在您的代码中发生任何变化(请注意,该name
声明是在Parent
中而不是在中声明的Child
),因此Child
不会被初始化,并且其静态块也不会被执行。
如果您执行一些操作来触发的初始化Child
,则会得到预期的输出:
new Child();
System.out.println(Child.name);
但是请注意,该静态字段不能被继承,因此Child.name
和Parent.name
实际指的是同一领域。这就是为什么在实践中使用类似于您的示例的代码没有多大意义。
还要注意,尽管实际上Child.name
实际上指的是Parent.name
,但它仍然Child.name
在字节码中被引用,因此您的代码触发的加载Child
,但不会触发其初始化。
问题内容: 我正在准备进行Java认证测试,并且发现了一个与Java静态块的执行有关的有趣问题。我已经花了很多时间阅读有关此主题的内容,但是找不到所需的答案。 我知道将类加载到JVM或调用main方法时会执行静态块,但是… 输出为: 如果我在中包含详细输出,则输出为: 我们可以在这里看到 Child类已加载 到JVM中。 有人可以解释 为什么类的静态块没有执行吗? 问题答案: 您看到该类已加载,但
我已经编写了以下代码,并为这个超类创建了对象。 当我检查输出时,如下所示: 我知道只有在初始化类的对象或进行任何静态引用时,才会执行静态块。但在这里,我并没有把这些都带到课堂上。那么为什么我会看到“sub”即sub类的静态块输出?
这是我的代码: 还有我的测试,我单独运行。 当我运行test foo时,我将看到: 但是当我运行测试栏时,我看到的是: 引用本页内容。。 类对象由Java虚拟机在加载类时自动构造,并通过调用类加载器中的defineClass方法来构造。 所以我的理解是,在测试条中,愚蠢的类被加载,否则我会看到一个空的,我猜?所以类对象被创建,因为类本身被加载。。 现在引用这一页 静态初始化块在JVM(类加载器-具
问题内容: 我正在查看Java代码,并注意到它使用了静态嵌套类。 使用静态嵌套类而不是普通内部类的原因是什么? 我能想到的唯一原因是Entry不能访问实例变量,因此从OOP的角度来看,它具有更好的封装性。 但是我认为可能还有其他原因,也许是性能。可能是什么? 注意。我希望我的术语正确,可以将其称为静态内部类,但是我认为这是错误的:http : //java.sun.com/docs/books/t
问题内容: 为什么不能修饰静态方法或类方法? 双方并导致。 为什么依赖属性而不是属性?(Afaik的所有函数(包括类方法和静态方法)都具有该属性。) 编辑:我正在使用Python 2.6。 问题答案: 当和是最高的装饰器时,它起作用:
问题内容: 当静态方法在子类中被重写时,我对它的行为感到困惑。 下面是代码: 为什么在第二种情况下在这里调用超类的静态方法? 如果方法不是静态的,则根据多态性,当在运行时传递子类对象时,将调用子类的方法。 问题答案: 静态方法的解析始终基于类型。 代码 编译后转换为此 对此,它是对方法的调用而不是对子类方法的调用。因此,您将获得方法的输出。