不能在定义之前引用一个字段,但前提是你没有限定它
Cannot reference a field before it is defined, but only if you don't qualify it
我发现下面的代码让我大吃一惊:
public class MCVE {
{ // instance initializer
System.out.println(test); // cannot reference a field before it is defined
System.out.println(this.test);
}
private final String test = "wat";
}
第 System.out.println(test);
行给出了错误
Cannot reference a field before it's defined.
但是 System.out.println(this.test);
行 不是
为什么这在我限定的时候不报错?
因为在您创建 lambda 时捕获 this
是可能的。捕获 test
不是(尚未定义)。不过稍后,在 lambda 中,您可以访问 test
(通过 this
)。
与其中许多问题一样,这是因为 the JLS says so.
8.3.2.3 Restrictions on the use of Fields during Initialization
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:
- The usage occurs in an instance (respectively
static
) variable initializer of C or in an instance (respectively static
) initializer of C.
- The usage is not on the left hand side of an assignment.
- The usage is via a simple name.
- C is the innermost class or interface enclosing the usage.
It is a compile-time error if any of the four requirements above are not met.
在您的(失败的)示例中,"simple name" 情况是不满足条件。限定用法(使用this
)是解决编译时错误的漏洞。
Explained another way:
The use of fields inside an initialization block before the line on which they are declared can only be on the left hand side of an expression (i.e. an assignment), unless they are qualified (in your case this.test
).
(为了更贴近这个问题而改写)
我发现下面的代码让我大吃一惊:
public class MCVE {
{ // instance initializer
System.out.println(test); // cannot reference a field before it is defined
System.out.println(this.test);
}
private final String test = "wat";
}
第 System.out.println(test);
行给出了错误
Cannot reference a field before it's defined.
但是 System.out.println(this.test);
行 不是
为什么这在我限定的时候不报错?
因为在您创建 lambda 时捕获 this
是可能的。捕获 test
不是(尚未定义)。不过稍后,在 lambda 中,您可以访问 test
(通过 this
)。
与其中许多问题一样,这是因为 the JLS says so.
8.3.2.3 Restrictions on the use of Fields during Initialization
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:
- The usage occurs in an instance (respectively
static
) variable initializer of C or in an instance (respectivelystatic
) initializer of C.- The usage is not on the left hand side of an assignment.
- The usage is via a simple name.
- C is the innermost class or interface enclosing the usage.
It is a compile-time error if any of the four requirements above are not met.
在您的(失败的)示例中,"simple name" 情况是不满足条件。限定用法(使用this
)是解决编译时错误的漏洞。
Explained another way:
The use of fields inside an initialization block before the line on which they are declared can only be on the left hand side of an expression (i.e. an assignment), unless they are qualified (in your case
this.test
).
(为了更贴近这个问题而改写)