How does an Enumeration variable works?

enums, java, object

Solution

Members of an `enum` in Java are just like static fields of a class, so `a1.DOG` is simply the same as `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???
    }
}

This doesn't only happen on `enum`s, but also `class`es:

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
    }
}

Just as @lichengwu has pointed out in his/her answer, `enum`s will finally compile into a class with static fields, so this is not a problem of `enum`s, but rather like the problem of `class`es.

In some other languages (for example C#) you are not allowed to reference a static member of a type through an instance of the type, but Java is an exception.

IMHO referencing a static member of a type through an instance of the type should be a bad habit. This causes confusion like you have pointed out.

If you like using the Eclipse IDE, it will simply give you a warning:

The static field Animals.DOG should be accessed in a static way

Eclipse also provides a few suggestions for you. One of them is to change to using the type to reference the `enum` member, and another one is to remove the "static modifier of the field" (but doesn't actually work on `enum`s).

Addition:

Internal structure of what the Enumeration compiles to:

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 {};
}

Problem

Consider `enum Animals { DOG, FISH, GOAT };` in Java. Now the variable of type `Animals` can point to member objects of this type: `Animals a1 = Animals.DOG;` that's fine. But how do the following chain references makes sense ? `Animals a2 = a1.DOG.FISH.GOAT;` (yea, looks crazy, seen this in a tricky Java question) what does `a1` really point to ? and how are we referencing other `enum` members from it ? Example: ``` public class EnumTest { enum Animals { DOG, FISH, GOAT }; public void test(){ Animals a1 = Animals.DOG; Animals a2 = a1.DOG.FISH.GOAT; //--Strange but valid-- } } ```

Original source