为什么在显式调用构造函数java时无法引用实例字段 [英] Why Cannot refer to instance fields while explicitly invoking a constructor java

查看:124
本文介绍了为什么在显式调用构造函数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()的执行顺序如下:


  1. B 及其依赖项的静态初始化被触发(如果尚未发生)。

  2. <$ c的参数表达式$ c> B 的构造函数参数被评估。 (在这种情况下,没有任何内容。)

  3. 创建一个堆节点,并使用 B 的类型进行初始化,然后所有字段(在 B 及其超类中)都默认初始化。

  4. super B 的c>参数。

  5. super 参数 A 被评估。

  6. 执行 Object()构造函数体。 / li>
  7. Ai Ay 的字段将被初始化(如果它们具有初始化器)

  8. 执行 A(int,int)构造函数体。

  9. B 的字段初始化程序将被执行。

  10. B()构造函数体被执行。

  11. 返回对已完成的 B 实例的引用。

  1. Static initialization for B and its dependents is triggered (if this hasn't happened already).
  2. Argument expressions for B's constructor parameters are evaluated evaluated. (There aren't any, in this case.)
  3. A heap node is created, initialized with B's type, and all fields (in B and its superclasses) are default initialized.
  4. The super parameters for B are evaluated.
  5. The super parameters for A are evaluated.
  6. The Object() constructor body is executed.
  7. The fields A.i and A.y would be initialized (if they had initializers).
  8. The A(int,int) constructor body is executed.
  9. B's field initializers would be executed.
  10. The B() constructor body is executed.
  11. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆