Eclipse关于Java中私有静态嵌套类的合成访问器的警告? [英] Eclipse warning about synthetic accessor for private static nested classes in Java?

查看:161
本文介绍了Eclipse关于Java中私有静态嵌套类的合成访问器的警告?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的同事建议将几个Eclipse代码格式化和警告设置更加严格。大多数这些变化是有道理的,但我在Java中得到了一个奇怪的警告。以下是一些重现问题的测试代码:

  package com.example.bugs; 

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

final私人内在类

{
this.anInstance = new InnerClass(); // !!!
this.anInstance.doSomething();
}
}
//使用this.anInstance而不是anInstance阻止另一个警告,
//不合格访问字段WeirdInnerClassJavaWarning.anInstance

行与!!!在我的新警告设置中给我这个警告:


访问封闭的构造函数
WeirdInnerClassJavaWarning.InnerClass()
由合成访问器
方法模拟。
可以提高您的表现。当我将私人静态类更改为protected static class时,警告消失,这对我来说没有任何意义。






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

  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的一个奇怪/ bug。



(道歉,我应该叫它的NestedClass而不是InnerClass更加清晰。)

解决方案

您可以摆脱以下警告:

  package com.example.bugs; 

public class WeirdInnerClassJavaWarning {
private static class InnerClass {
protected InnerClass(){} //此构造函数使警告消失
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构造函数:
private InnerClass(){}

//由JAVA编译器生成的合成方法:
InnerClass(InnerClass innerclass){
this();
}
}

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

//编译器修改的实例初始化:
private final InnerClass anInstance = new InnerClass(null);
}

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



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


My coworker suggested making several of the Eclipse code-formatting and warning settings to be more rigorous. The majority of these changes make sense, but I get this one weird warning in Java. Here's some test code to reproduce the "problem":

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    

The line with the !!! gives me this warning in Eclipse with my new warning settings:

Access to enclosing constructor WeirdInnerClassJavaWarning.InnerClass() is emulated by a synthetic accessor method. Increasing its visibility will improve your performance.

What does this mean? The warning goes away when I change "private static class" to "protected static class", which makes no sense to me.


edit: I finally figured out the "correct" fix. The real problem here seems to be that this nested private static class is missing a public constructor. That one tweak removed the warning:

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();
    }
}

I want the class to be a private nested class (so no other class can have access to it, including subclasses of the enclosing class) and I want it to be a static class.

I still don't understand why making the nested class protected rather than private is another method of fixing the "problem", but maybe that is a quirk/bug of Eclipse.

(apologies, I should have called it NestedClass instead of InnerClass to be more clear.)

解决方案

You can get rid of the warning as follows:

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();
    }
}

As others have said, Eclipse is complaining because a private class with no explicit constructor cannot be instantiated from outside, except via the synthetic method that the Java compiler creates. If you take your code, compile it, and then decompile it with jad (*), you get the following (reformatted):

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);
}

If you add a protected constructor, the synthetic code is unnecessary. The synthetic code is theoretically, I suppose, slower by a minescule amount than non-synthetic code using a public or protected constructor.

(*) For jad, I linked to a Wikipedia page ... the domain that hosted this program has expired, but Wikipedia links to another that I have not tested myself. I know there are other (possibly more recent) decompilers, but this is the one I started using. Note: It complains when decompiling recent Java class files, but it still does a good job.

这篇关于Eclipse关于Java中私有静态嵌套类的合成访问器的警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆