我有一个包含以下内容的课程:
引用内部类内部的枚举常量生成合成访问器警告,但引用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
}
}
}
答案 0 :(得分:2)
JLS要求将对编译时常量的访问“内联”到消费类中,而不是在链接和运行时留下符号引用。特别是来自JLS 13.1:
- 对作为常量变量的字段(第4.12.4节)的引用是 在编译时解析为表示的常量值。没有 对这样一个字段的引用应该存在于二进制代码中 文件(包含该字段的类或接口除外) 将有代码来初始化它。)
醇>
特别是,这意味着您的类Inner
在其已编译的类文件中没有Outer.FOO
的任何痕迹。相反,FOO
的常量值0在编译时直接编译为Inner
。
合成访问方法(以及其他原因)被添加以便于运行时访问嵌套类之间的私有字段 - 但在FOO
的情况下,访问已在编译时解决,所以不需要任何方法。
Outer.BAR
不符合编译时常量处理的条件 - 因为某些String
对象以外的对象不是15.28的编译时常量:
编译时常量表达式是表示值的表达式 原始类型或不突然完成的字符串,是 仅使用以下内容撰写...
Enum
既不是原语也不是String
,因此编译时常量的特殊处理不适用,并且会生成合成访问器方法。