关于 Java 中私有静态嵌套类的综合访问器的 Eclipse 警告?

我的同事建议对一些 Eclipse 代码格式化和警告设置进行更严格的设置。这些更改中的大多数都是有道理的,但我在Java中得到了一个奇怪的警告。下面是一些重现“问题”的测试代码:

package com.example.bugs;

public class WeirdInnerClassJavaWarning {
    private static class InnerClass
    {
        public void doSomething() {}
    }

    final private InnerClass anInstance;

    {
        this.anInstance = new InnerClass();   // !!!
        this.anInstance.doSomething();
    }
}
// using "this.anInstance" instead of "anInstance" prevents another warning,
// Unqualified access to the field WeirdInnerClassJavaWarning.anInstance    

带有!!!的线在 Eclipse 中用我的新警告设置给我这个警告:

对封闭构造函数 WeirdInnerClassJavaWarning.InnerClass() 的访问由合成访问器方法模拟。提高其可见性将提高您的性能。

这是什么意思?当我将“私有静态类”更改为“受保护的静态类”时,警告消失了,这对我来说毫无意义。


编辑:我终于找到了“正确”的修复方法。这里真正的问题似乎是这个嵌套的私有静态类缺少一个公共构造函数。那一个调整删除了警告:

package com.example.bugs;

public class WeirdInnerClassJavaWarning {
    private static class InnerClass
    {
        public void doSomething() {}
        public InnerClass() {}
    }

    final private InnerClass anInstance;

    {
        this.anInstance = new InnerClass();
        this.anInstance.doSomething();
    }
}

我希望该类是私有嵌套类(因此没有其他类可以访问它,包括封闭类的子类),并且我希望它是静态类。

我仍然不明白为什么使嵌套类受到保护而不是私有是解决“问题”的另一种方法,但也许这是Eclipse的一个怪癖/错误。

(抱歉,我应该把它叫做NestedClass而不是InnerClass,以便更清楚。


答案 1

您可以按如下方式删除警告:

package com.example.bugs;

public class WeirdInnerClassJavaWarning {
    private static class InnerClass {
        protected InnerClass() {}  // This constructor makes the warning go away
        public void doSomething() {}
    }

    final private InnerClass anInstance;
    {
        this.anInstance = new InnerClass(); 
        this.anInstance.doSomething();
    }
}

正如其他人所说,Eclipse之所以抱怨,是因为没有显式构造函数的私有类不能从外部实例化,除非通过Java编译器创建的综合方法。如果您获取代码,对其进行编译,然后使用 jad (*) 反编译它,则会得到以下内容(重新格式化):

public class Test {
  private static class InnerClass {
    public void doSomething() {}
    // DEFAULT CONSTRUCTOR GENERATED BY COMPILER:
    private InnerClass() {}

    // SYNTHETIC METHOD GENERATED BY THE JAVA COMPILER:    
    InnerClass(InnerClass innerclass) {
      this();
    }
  }

  public Test() {
    anInstance.doSomething();
  }

  // Your instance initialization as modified by the compiler:
  private final InnerClass anInstance = new InnerClass(null);
}

如果添加受保护的构造函数,则不需要综合代码。我认为,从理论上讲,合成代码比使用公共或受保护的构造函数的非合成代码慢得多。

(*)对于jad,我链接到维基百科页面...托管此程序的域已过期,但维基百科链接到我自己尚未测试的另一个域。我知道还有其他(可能是最近的)反编译器,但这是我开始使用的那个。注意:在反编译最近的 Java 类文件时,它会抱怨,但它仍然做得很好。


答案 2

顺便说一句,关闭警告的设置位于“代码样式”下的Java错误/警告页面中,称为:

访问封闭类型的不可访问成员


推荐