为什么在显式调用构造函数java时无法引用实例字段 [英] Why Cannot refer to instance fields while explicitly invoking a constructor java
问题描述
我有以下简单的课程。
class A {
int i;
int y;
A(int i, int y)
{
}
,然后当我尝试在以下级别进行操作
and then when I try to do below
class B extends A
{
B()
{
super(i, y);
}
}
我收到错误消息,说
无法在显式调用构造函数时,请参考实例字段y。
我知道这是错误的,但是我想知道为什么我不能这样做。由于A的构造函数首先被初始化,因此i和y的值均为0,为什么不能将这些值传递给超级构造函数。
I get the error saying "Cannot refer to an instance field y while explicitly invoking a constructor". I know this is wrong but I want to know why I cannot do this. Since A's constructor gets initialized first it has 0 value for both i and y and why cannot pass those values to super constructor.
推荐答案
由于A的构造函数首先被初始化,所以i和y的值均为0,为什么不能将这些值传递给超级构造函数。
Since A's constructor gets initialized first it has 0 value for both i and y and why cannot pass those values to super constructor.
问题在于 super(i,y)
(在 B
中)将在调用 A
构造函数之前进行评估。
The problem is that expressions for the arguments in super(i, y)
(in B
) are evaluated before calling the A
constructor.
new B()
的执行顺序如下:
-
B
及其依赖项的静态初始化被触发(如果尚未发生)。 - <$ c的参数表达式$ c> B 的构造函数参数被评估。 (在这种情况下,没有任何内容。)
- 创建一个堆节点,并使用
B
的类型进行初始化,然后所有字段(在B
及其超类中)都默认初始化。 -
super $ c $评估
B
的c>参数。 -
super
参数A
被评估。 - 执行
Object()
构造函数体。 / li>
-
Ai
和Ay
的字段将被初始化(如果它们具有初始化器) - 执行
A(int,int)
构造函数体。 -
B
的字段初始化程序将被执行。 -
B()
构造函数体被执行。 - 返回对已完成的
B
实例的引用。
- Static initialization for
B
and its dependents is triggered (if this hasn't happened already). - Argument expressions for
B
's constructor parameters are evaluated evaluated. (There aren't any, in this case.) - A heap node is created, initialized with
B
's type, and all fields (inB
and its superclasses) are default initialized. - The
super
parameters forB
are evaluated. - The
super
parameters forA
are evaluated. - The
Object()
constructor body is executed. - The fields
A.i
andA.y
would be initialized (if they had initializers). - The
A(int,int)
constructor body is executed. B
's field initializers would be executed.- The
B()
constructor body is executed. - The reference to completed
B
instance is returned.
如您所见,第4步指的是 y
已初始化 1 。在第7步之前,不会对其进行初始化。
As you can see, step 4 refers to y
which hasn't been initialized yet1. It won't be initialized until step 7.
注意:以上已简化。请参考 JLS 15.9.4 以获得完整说明。
Note: the above is simplified. Refer to JLS 15.9.4 for the full specification.
1-规则未考虑到这一事实您的示例中没有初始化程序。但这是一件好事。 1)考虑到这一点会使它们变得更加复杂,并且……令人惊讶。 2)如果您知道具有默认值,则允许访问变量的实用工具是什么?您可以直接使用该值!
1 - The rules don't take account of the fact that there is no initializer in your example. But that's a good thing. 1) Taking account of that would make them more complicated and ... surprising. 2) What is the utility of allowing access to a variable if you know it has the default value? You could just use that value directly!
这篇关于为什么在显式调用构造函数java时无法引用实例字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!