What are the differences between a Java enum and a class with private constructor?

user9349193413 picture user9349193413 · Mar 31, 2013 · Viewed 42.7k times · Source

I was trying to understand how Java enum really works and I have come to the conclusion that it is very similar to a normal Java class that has its constructor declared private.

I have just come to this conclusion and it isn't based on much thinking, but Id like to know whether I miss anything.

So below is an implementation of a simple Java enum and an equivalent Java class.

public enum Direction {
    ENUM_UP(0, -1),
    ENUM_DOWN(0, 1),
    ENUM_RIGHT(1, 0),
    ENUM_LEFT(-1, 0);


    private int x;
    private int y;

    private Direction(int x, int y){
        this.x = x;
        this.y = y;
    }
    public int getEnumX(){
        return x;
    }
    public int getEnumY(){
        return y;
    }
}

What is the difference in meaning between the code above and below?

public class Direction{
    public static final Direction UP = new Direction(0, -1) ;
    public static final Direction DOWN = new Direction(0, 1) ;
    public static final Direction LEFT = new Direction(-1, 0) ;
    public static final Direction RIGHT = new Direction(1, 0) ;


    private int x ;
    private int y ;

    private Direction(int x, int y){
        this.x = x ;
        this.y = y ;
    }
    public int getX(){
        return x;
    }
    public int getY(){
        return y;
    }
}

Answer

nneonneo picture nneonneo · Mar 31, 2013

Differences:

  1. Enums extend java.lang.Enum and gain all of its nice features:
    1. Automatic singleton behaviour through correct serialization
    2. Automatic human-readable .toString method on enum values without the need to duplicate your enum names
    3. .name and .ordinal special-purpose methods
    4. Usable in high-performance bitset-based EnumSet and EnumMap classes
  2. Enums are treated by the language specially:
    1. Enums use a special syntax which simplifies instance creation without writing dozens of public static final fields
    2. Enums can be used in switch statements
    3. Enums cannot be instantiated outside the enumeration list except by using reflection
    4. Enums cannot be extended outside the enumeration list
  3. Java automatically compiles extra stuff into enums:
    1. public static (Enum)[] values();
    2. public static (Enum) valueOf(java.lang.String);
    3. private static final (Enum)[] $VALUES; (values() returns a clone of this)

Most of these can be emulated with a suitably designed class, but Enum just makes it really easy to create a class with this set of particularly desirable properties.