首先,由于缺乏
someLookup方法,该代码无法编译。
无论如何,我相信您的问题是,由于构造函数是分层运行的,您的期望是无效的。
超类的构造函数始终在子类的构造函数之前运行,这包括子类的变量的初始化程序(实际上是作为构造函数的一部分运行)。因此,当您创建的实例时
Derived,会发生以下情况:
- 该
base
构造函数首先被调用。 lookup()
被调用,它使用中的实现Derived
。num
返回 值 , 这是默认值,因为尚未运行Derived的构造函数和初始化程序 。val
设置为0。- 在
Derived
初始化和构造都运行-呼吁lookup
从 这个 点上会返回10。
通常,正是出于这个原因,从构造函数中调用非最终方法是一个坏主意,许多静态分析工具都会警告您。这类似于在构造过程中让对象引用泄漏,您可以得到一个实例,该实例使类级不变式失效(在您的情况下,Derived的
num“总是”为10,但在某些情况下可以看到为0)。
编辑:请注意,对于这种 特殊 情况,无需任何其他代码,您可以通过使
num常量来解决问题:
class Derived extends base{ private static final int num = 10; ...这实际上会做您想要的事情,因为静态初始化程序是在加载类时运行的(必须在调用构造函数之前发生)。但是,这确实假定适用于:
a)该类的所有实例共享相同的
num变量;b)
num无需更改(如果为true,则(a)自动为true)。
在给出的确切代码中,显然是这样,但是我希望您可能为了简洁而省略了额外的功能。
我将其包括在这里是出于比较和关注的目的,不是因为从一般意义上说,这是针对该“问题”的解决方法(因为不是这样)。



