java - 这里指的是什么变量?
问题描述
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);
}
就个人而言,我宁愿看到代码的第二种形式,因为对第一种形式的评估似乎很模糊。
推荐阅读
- jsonschema - PHP 数组和 JSON 模式
- c - 防止使用(优化复制)数据段到本地堆栈数据结构/数组
- sql-server - 从表 1 中的 id 返回表 2 中的名称的问题
- python - Python Text Summarizer - 维护句子顺序
- javascript - 如何使这段 Javascript 代码更高效?
- javascript - javascript/jquery - 如何从重复出现的父类中获取子类名称的变量
- python - 热切掉不同字符串中的文本?
- android - Gradle如何用'variant.getPackageLibraryProvider()'替换过时的'variantOutput.getPackageLibrary()'?
- python - 熊猫重命名索引
- react-select - React-select isMulti 在版本 1 中不起作用