为什么当我在变量声明中使用引用 this
时,不出现非法前向引用?使用 this
和不使用它的声明有什么区别?
以下示例由于非法前向引用而无法编译:
class FailsToCompile {
int a = b; //illegal forward reference
int b = 10;
}
通过限定 this
对 b
的使用,编译错误消失了。
class Compiles {
int a = this.b; //that's ok
int b = 10;
}
假设下面的类
public class MyClass {
int a = b;
int b = 10;
}
JLS 8.3.3.在你的情况下状态:
Use of instance variables whose declarations appear textually after the use is sometimes restricted
- The use is a simple name in either an instance variable initializer of C or an instance initializer of C
现在,使用成员 this
允许您访问已声明为默认值(a = 0, b = 0
)但尚未完全初始化的实例.如果您检查以下结果,这是可见的:
public class MyClass {
int a = this.b;
int b = 10;
}
你不会得到预期的值(value):
new MyClass().a //0
new MyClass().b //10
我无法解释为什么这是合法的,因为这永远不会给出正确的值。我们可以找到一些关于为什么存在限制的解释:
The restrictions above are designed to catch, at compile time, circular or otherwise malformed initializations.
但是为什么允许 this
工作...
知道在实例初始化期间,会发生以下操作:
- 成员声明
- 按顺序执行 block 和Field初始化
- 构造函数执行
给出一些奇怪的行为:
public class MyClass {
{
b = 10;
}
int a = this.b;
int b = 5;
{
b = 15;
}
public static void main(String[] args) {
MyClass m = new MyClass();
System.out.println(m.a); //10
System.out.println(m.b); //15
}
}
我会限制构造函数中的初始化。