Nested enum is static?
在阅读这个问题时,我打开编辑器,尝试一些代码示例来验证和理解它。以下是我的代码:
1 2 3 4 5 6 7 8 9 10 11 | public enum EnumImpl { B { public void method() { System.out.println(s); //(1)non-static variable s cannot be referenced from a static context } public static int b; //(2)Illegal static declaration in inner class }; private int s; } |
但是编译上面的代码让我更加困惑。
- 第一个错误是什么上面的问题表明
B 实际上属于静态类。所以在method 中,它是一个静态上下文。 - 相反,第二个错误是,这里是一个内部类——非静态嵌套类,如Java DOC所说。
- 下面是我从JLS引用的一行,但它似乎有点混乱和模糊。
A nested enum type is implicitly static.
以下是匿名合成类b的字节码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14final class enum_type.EnumImpl$1 extends enum_type.EnumImpl {
enum_type.EnumImpl$1(java.lang.String, int);
Code:
0: aload_0
1: aload_1
2: iload_2
3: aconst_null
4: invokespecial #1 // Method enum_type/EnumImpl."<init>":(Ljava/lang/String;ILenum_type/EnumImpl$1;)V
7: return
public void method();
Code:
0: return
}
那么B类是静态的还是非静态的?
@lew bloch似乎说的是这样的(行为与上面的枚举示例相匹配,但是如果这是真的,那么链接问题的答案在某些意义上是错误的)。
1 2 3 4 5 6 7 8 9 10 11 | abstract class Cmp { private int s; static { class Bclass extends Cmp { public void method() { // System.out.println(s); } // private static int b; } } } |
你对
实例子类型在枚举常量的静态初始值设定项中声明。因为上下文是静态的,所以它不能访问枚举实例变量。
枚举声明不是静态的,它是顶级的,顶级类不能是静态的。
常量体定义枚举的隐式嵌套匿名子类,并且不构成jls所指的嵌套枚举。每个常量都属于要声明的枚举的不同匿名子类型,而该子类型不是静态的。但是,子类型是在静态上下文中声明的,因此代码无法到达实例变量。
编辑:来自JLS的有用参考资料
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html jls-8.9.1"枚举常量的可选类主体隐式定义了一个匿名类声明(§15.9.5),该声明扩展了立即封闭的枚举类型。类主体由匿名类的常规规则控制;特别是它不能包含任何构造函数。只有当这些类实体中声明的实例方法重写封闭枚举类型(§8.4.8)中的可访问方法时,才能在封闭枚举类型之外调用它们。
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html jls-15.9.5"匿名类声明是由Java编译器从类实例创建表达式自动派生的。匿名类从不抽象(§8.1.1.1)。匿名类始终是隐式的最终类(§8.1.1.2)。匿名类始终是一个内部类(§8.1.3);它从不是静态的(§8.1.1,§8.5.1)。"