Enumeration变量如何工作?

S.D*_*.D. 16 java enums object

考虑enum Animals { DOG, FISH, GOAT };用Java.

现在,类型的变量Animals可以指向此类型的成员对象:

Animals a1 = Animals.DOG; 没关系.

但是,以下链引用如何才有意义呢?

Animals a2 = a1.DOG.FISH.GOAT; (是的,看起来很疯狂,在一个棘手的Java问题中看到这个)

什么a1 真正指向?我们如何enum从中引用其他成员?

例:

public class EnumTest {
    enum Animals { DOG, FISH, GOAT };

    public void test(){
        Animals a1 = Animals.DOG;
        Animals a2 = a1.DOG.FISH.GOAT; //--Strange but valid--
    }
}
Run Code Online (Sandbox Code Playgroud)

Alv*_*ong 12

enumJava中的成员就像一个类的静态字段,因此a1.DOG就像是一样Animals.DOG.

public class EnumTest {
    enum Animals { DOG, FISH, GOAT };

    public void test(){
        Animals a1 = Animals.DOG;
        Animals a2 = a1.DOG; // the same as Animals.DOG, but makes code messy
        Animals a3 = a1.DOG.FISH; // WTF chaining???
    }
}
Run Code Online (Sandbox Code Playgroud)

这不仅发生在enums上,而且发生在class:

public class A {
    public static A a_1;
    public static A a_2;

    public void boo() {
        A a = A.a_1;
        A b = a.a_1; // That makes a equal to b!
        A c = a.a_1.a_2; // I HATE "CHAINING" LIKE THIS
    }
}
Run Code Online (Sandbox Code Playgroud)

就像@lichengwu在他/她的回答中指出的那样,enums最终会编译成一个带有静态字段的类,所以这不是enums 的问题,而是classes 的问题.

在某些其他语言(例如C#)中,不允许通过类型的实例引用类型的静态成员,但Java是一个例外.

恕我直言通过该类型的实例引用类型的静态成员应该是一个坏习惯.这会引起你所指出的混乱.


如果您喜欢使用Eclipse IDE,它只会给您一个警告:

应以静态方式访问静态字段Animals.DOG

Eclipse还为您提供了一些建议.其中之一是更改为使用类型来引用enum成员,另一个是删除"字段的静态修饰符"(但实际上并不适用于enums).

加成:

枚举编译的内部结构:

final class Animals extends java.lang.Enum<Animals> {
  public static final Animals DOG;
  public static final Animals FISH;
  public static final Animals GOAT;
  public static Animals[] values();
  public static Animals valueOf(java.lang.String);
  static {};
}
Run Code Online (Sandbox Code Playgroud)


lic*_*gwu 5

反编译了 Animals.class

javap Animals.class:

final class Animals extends java.lang.Enum<Animals> {
  public static final Animals DOG;
  public static final Animals FISH;
  public static final Animals GOAT;
  public static Animals[] values();
  public static Animals valueOf(java.lang.String);
  static {};
}
Run Code Online (Sandbox Code Playgroud)

所有类型都是Animals的实例,因此您可以引用其他类型.