为什么访问此私有枚举常量需要合成访问器?

时间:2016-06-02 19:04:19

标签: java

我有一个包含以下内容的课程:

  • 一个公共的,静态的内部枚举
  • 引用int和enum的私有常量
  • 私人内部课程

引用内部类内部的枚举常量生成合成访问器警告,但引用int常量不会。

这是为什么?如何在不使枚举常量包范围或禁用警告的情况下阻止此警告? (例如,可能通过制作一个明确的访问者?)

重现问题的代码:

public class Outer {
    public static enum Bar {
        A, B, C;
    }

    private static final int FOO = 0;
    private static final Outer.Bar BAR = Outer.Bar.A;

    private class Inner {
        {
            int foo = Outer.FOO;        // just fine
            Outer.Bar bar = Outer.BAR;  // synthetic accessor method warning
        }
    }
}

1 个答案:

答案 0 :(得分:2)

JLS要求将对编译时常量的访问“内联”到消费类中,而不是在链接和运行时留下符号引用。特别是来自JLS 13.1

  
      
  1. 对作为常量变量的字段(第4.12.4节)的引用是   在编译时解析为表示的常量值。没有   对这样一个字段的引用应该存在于二进制代码中   文件(包含该字段的类或接口除外)   将有代码来初始化它。)
  2.   

特别是,这意味着您的类Inner在其已编译的类文件中没有Outer.FOO的任何痕迹。相反,FOO的常量值0在编译时直接编译为Inner

合成访问方法(以及其他原因)被添加以便于运行时访问嵌套类之间的私有字段 - 但在FOO的情况下,访问已在编译时解决,所以不需要任何方法。

另一方面,

Outer.BAR不符合编译时常量处理的条件 - 因为某些String对象以外的对象不是15.28的编译时常量:

  

编译时常量表达式是表示值的表达式   原始类型或不突然完成的字符串,是   仅使用以下内容撰写...

Enum既不是原语也不是String,因此编译时常量的特殊处理不适用,并且会生成合成访问器方法。