Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does an Enumeration variable works?

Tags:

java

object

enums

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--
    }
}
like image 506
S.D. Avatar asked Dec 23 '12 14:12

S.D.


1 Answers

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 enums, but also classes:

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, enums will finally compile into a class with static fields, so this is not a problem of enums, but rather like the problem of classes.

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 enums).

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 {};
}
like image 50
Alvin Wong Avatar answered Oct 12 '22 02:10

Alvin Wong