class Test {
int a;
void method() {
a = 1;
int a = a = 2;
a = 3;
}
}
里面有很多a
s method
。他们都指的是什么?
class Test {
int a;
void method() {
a = 1;
int a = a = 2;
a = 3;
}
}
里面有很多a
s method
。他们都指的是什么?
这是 Java 范围规则的奇异性的一个简单示例。
a = 1;
int a = a = 2;
a = 3;
逐行分解:
a = 1;
是指成员变量。a = 3;
是指局部变量,因为它在局部变量的声明之后。您可以通过相同的标识符以相同的方法引用两个不同的符号,这非常令人困惑。int a = a = 2;
: 第二个a
是局部变量。变量声明中的自引用真的很好奇。您可以在语言规范中找到它:
- 块中局部变量声明的范围(第 14.4 节)是声明出现的块的其余部分,从它自己的初始化程序开始,并在局部变量声明语句的右侧包括任何进一步的声明符。
成员变量也可以在它们自己的初始化器中引用它们自己。但这是出于稍微不同的原因:
- 在类类型 C(第 8.1.6 节)中声明或继承的成员 m 的声明范围是 C 的整个主体,包括任何嵌套类型声明。
我还没有找到一个令人信服的理由来证明这个局部变量规则的存在;也许您只是真的很想确保它已分配。我认为它允许您做的唯一一件事就是在初始化器的评估中使用变量作为临时存储,例如:
int a = method(a = somethingThatIsReallyExpensiveToCompute(), a);
相当于:
int a;
{
int tmp = somethingThatIsReallyExpensiveToCompute();
a = method(tmp, tmp);
}
就个人而言,我宁愿看到代码的第二种形式,因为对第一种形式的评估似乎很模糊。