java - 为什么在实例初始值设定项内不允许递增 (`x++;` )但未声明的字段,但如果包装到匿名类中则可以?

标签 java constructor field anonymous-class initializer

我很困惑为什么在实例初始值设定项内不允许递增但未声明的字段 (x++;),但如果包装到匿名类中,则在实例初始值设定项内允许它(是的,匿名类具有访问类字段,但该字段未初始化!)。

class Test {

    { x++; }  // ERR: Cannot reference a field before it is defined

    Object anonFld = new Object() {     
        { x++; }     // fine! Sets x field below to 1 !

        void f() {
            x++; // fine!
        }
    };
    int x;

    // now x = 1     // anon constructor has set it!    

}

最佳答案

JLS, Section 8.3.3 ,给出了为前向引用给出编译器错误的规则。

For a reference by simple name to an instance variable f declared in class C, it is a compile-time error if:

  • The reference appears either in an instance variable initializer of C or in an instance initializer of C (§8.6); and

  • The reference appears in the initializer of f's own declarator or at a point to the left of f's declarator; and

  • The reference is not on the left hand side of an assignment expression (§15.26); and

  • The innermost class enclosing the reference is C.

对于来自嵌套类或内部类的引用,没有提供编译器错误的规定。奇怪的是,非简单引用可以访问前向引用,例如

this.x++;

此外,稍后在同一部分中,有一个示例明确指出可以从不同的类进行访问。

class UseBeforeDeclaration {
    // Snipped
    {
      // Snippped
        j = j + 1;
      // error - right hand side reads before declaration
      // Snipped
      Object o = new Object() { 
          void foo(){ j++; }
            // ok - occurs in a different class
          { j = j + 1; }
            // ok - occurs in a different class
      };
  }
  // Snipped
  int j;
}

我只包含了相关部分——使用内部类进行前向引用的实例初始值设定项,以及末尾的声明。

关于java - 为什么在实例初始值设定项内不允许递增 (`x++;` )但未声明的字段,但如果包装到匿名类中则可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56996942/

相关文章:

c++ - 重载的赋值运算符不起作用

java - 动态创建 FormLayout 行和列(在运行时)

java - Android 自定义 ListView 不使用 Volley 构建

java - 从其他 fragment 控制蓝牙

java - 为什么两种情况下的输出不同?

twitter-bootstrap - 带有 CKEditor 的 Bootstrap 等于问题

python - 在同一模块的字段中加载类 - OpenErp

java - 我可以直接从java代码调用spring集成链元素吗?

java - 类构造函数上的 JSP 编译错误

c++ - 无法初始化类成员?