为什么我们允许在Java中引用枚举成员的枚举成员?

Che*_*eng 20 java enums

鉴于以下枚举:

enum Repeat {
    Daily,
    Weekly,
    Yearly
}
Run Code Online (Sandbox Code Playgroud)

我意识到我们能够这样写它:

Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;
Run Code Online (Sandbox Code Playgroud)

这相当于:

Repeat repeat = Repeat.Weekly;
Run Code Online (Sandbox Code Playgroud)

我可以知道为什么允许这样的语法吗?有没有办法让编译器警告我们不要这样做?

Ami*_*era 19

这是允许的,因为它Daily, Weekly, Yearly是在内部的static字段并保持对象.此外,您将收到编译器的警告.它类似于下面的代码行.defaultenumRepeat"The static field Repeat.Weekly should be accessed in a static way"

class Foo{
    public static Foo obj1 = new Foo();
    public static Foo obj2 = new Foo();
    public static Foo obj3 = new Foo();
}

Foo f = Foo.obj1.obj2.obj3; // will work fine but you will get a warning from the compiler.
Run Code Online (Sandbox Code Playgroud)

这是Repeat枚举的字节码检查的一部分,从中可以清楚地看到Enum变量是static并且保存了Enum本身的对象.

   0: new           #1                  // class com/java8/demo/Repeat
   3: dup
   4: ldc           #14                 // String Daily
   6: iconst_0
   7: invokespecial #15                 // Method "<init>":(Ljava/lang/String;I)V
  10: putstatic     #19                 // Field Daily:Lcom/java8/demo/Repeat;
  13: new           #1                  // class com/java8/demo/Repeat 
Run Code Online (Sandbox Code Playgroud)


Mạn*_*yễn 5

枚举实例只是static枚举类的实例.

我们有两种访问类的静态字段的方法:

  1. 通过类itselft:Repeat.Daily
  2. 通过类的实例:Repeat.Daily.Daily

链接枚举时:

Repeat repeat = Repeat.Daily.Weekly.Yearly.Weekly;
Run Code Online (Sandbox Code Playgroud)

就像从类的实例中获取静态字段一样.