【问题标题】:What variable is being referred to here?这里指的是什么变量?
【发布时间】:2023-03-10 05:14:02
【问题描述】:
class Test {
  int a;

  void method() {
    a = 1;
    int a = a = 2;
    a = 3;
  }
}

method 中有很多 as。他们都指的是什么?

【问题讨论】:

    标签: java language-lawyer language-specifications


    【解决方案1】:

    这是一个简单的例子,说明 Java 范围规则的奇异性。

    a = 1;
    int a = a = 2;
    a = 3;
    

    逐行分解:

    • a = 1; 指的是成员变量。
    • a = 3; 指的是局部变量,因为它在局部变量的声明之后。您可以通过相同的标识符以相同的方法引用两个不同的符号,这非常令人困惑。
    • int a = a = 2;:第二个a局部变量

    变量声明中的自引用真的很好奇。你可以找到这个in the language spec

    • 块中局部变量声明的范围(第 14.4 节)是该声明出现的块的其余部分,从它自己的初始化程序开始,并在右侧包括任何进一步的声明符局部变量声明语句。

    成员变量也可以在自己的初始化器中引用自己;但这是出于稍微不同的原因:

    • 在类类型 C(第 8.1.6 节)中声明或继承的成员 m 的声明范围是 C 的整个主体,包括任何嵌套类型声明。

    我还没有找到一个令人信服的理由来证明这个局部变量规则的存在;也许您只是真的想确保它已分配。我认为它允许您做的唯一一件事就是在初始化器的评估中将变量用作临时存储,例如:

    int a = method(a = somethingThatIsReallyExpensiveToCompute(), a);
    

    相当于:

    int a;
    {
      int tmp = somethingThatIsReallyExpensiveToCompute();
      a = method(tmp, tmp);
    }
    

    就我个人而言,我宁愿看代码的第二种形式,因为第一种形式的评估似乎很模糊。

    【讨论】:

    • 当他们从变量的作用域中排除变量的初始化器时,int a = a; 是一个有效的语句,即当外部作用域中有另一个 a 时,就像在你的例子中一样。现在,如果这不是晦涩难懂的话……
    • @Holger 有趣的一点。当然,纯粹是凝视,但我想知道是否有可能使 两者都不 在范围内,并且避免两种晦涩难懂...!
    • 尽管有上面的 java 规范摘录,仅使用从左到右规则和优先规则,int a = a = 2; 可以分解为:int a = (a = 2);,然后是 int a; a = 2; a = a;
    猜你喜欢
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    相关资源
    最近更新 更多