当我添加“this”时,递归初始值设定项有效吗? [英] Recursive initializer works when I add "this"?

查看:105
本文介绍了当我添加“this”时,递归初始值设定项有效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无法编译(使用非法转发引用错误),正如人们所期望的那样:

This fails to compile (with an illegal forward reference error), as one would expect:

class test {
    int x = x + 42;
}

但这样可行:

class test {
    int x = this.x + 42;
}

发生了什么事?在后一种情况下分配了什么?

What's going on? What gets assigned in the latter case?

推荐答案

摘要:两个初始值设定项都访问一个尚未初始化的字段(因此仍然具有默认值为零)。由于这可能是编程错误,因此该语言禁止这种访问的一些简单形式。但是,它并没有禁止更复杂的形式。

Summary: Both initializers access a field that's yet to be initialized (and therefore still has the default value of zero). Since this is likely to be a programming error, the language bans some simple forms of such access. However, it does not ban more complex form.

该行为符合JLS,特别是§8.3.2.3。初始化期间使用字段的限制

The behaviour is compliant with the JLS, specifically §8.3.2.3. Restrictions on the use of Fields during Initialization


成员的声明只有在使用前才需要以文本方式显示member是类或接口 C 的实例(分别为 static )字段,并且满足以下所有条件:

The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:


  • 用法发生在一个实例(分别是 static )变量初始值设定项中C或实例(分别是静态)C的初始值设定项。

  • The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.

用法不在作业的左侧。

使用方法是通过一个简单的名称。

The usage is via a simple name.

C 是封闭用法的最里面的类或接口。

C is the innermost class or interface enclosing the usage.

第一个例子满足所有四个条件,因此无效。第二个例子不满足第三个条件( this.x 不是一个简单的名字),因此没问题。

The first example satisfies all four conditions and is therefore invalid. The second example doesn't satisfy the third condition (this.x is not a simple name), and is therefore OK.

事件的整体顺序如下:

  • When an instance of a class is created, all fields are initialized to their type's default values.
  • Initializers are then run in textual order (from top to bottom).

因此,如果初始化程序引用了在类定义中稍后出现的字段(或字段本身),则会看到该其他字段的默认值。这可能是一个编程错误,因此§8.3.2.3明确禁止。

Thus if an initializer refers to a field that appears later in the class definition (or to the field itself), it would see the default value of that other field. This is likely to be be a programming error and is therefore explicitly forbidden by §8.3.2.3.

如果你绕过§8.3.2.3,例如,使用 this。转发 - 引用一个字段,你会看到默认值(零 int )。因此,以下是明确定义的,并保证将 x 设置为 42

If you circumvent §8.3.2.3 by, for example, using this. to forward-refer to a field, you'll see the default value (zero for int). Thus the following is well-defined and is guaranteed to set x to 42:

class test {
    int x = this.x + 42;
}

这篇关于当我添加“this”时,递归初始值设定项有效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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