5

I was helping a friend with Java the other day, and they were asking about Enums. I explained that the C syntax of (something like)

enumeration Difficulty{
    BEGINNER= 1;
    PRO=5;
    EXPERT = 11;
}

Wasn't the way to go, the Java syntax is something(1); you made a constructor that accepted an int and then did this and that...etc.

But they stopped me and asked "If we're using constructors and so on, why bother with an enum, why not just have a new class?"

And I couldn't answer. So why would you use an enum in this case, and not a class?

AncientSwordRage
  • 7,086
  • 19
  • 90
  • 173
  • 2
    Enum are special type of classes. Before Java5, it used to be implemented as classes/interfaces, Enums are mainly for type-safe. – kosa Aug 14 '12 at 13:51
  • All is clearly axplain by Joshua Bloch http://www.pascal-man.com/navigation/faq-java-browser/java-concurrent/Effective%20Java%20-%20Programming%20Language%20Guide.pdf – cl-r Aug 14 '12 at 13:57

7 Answers7

10

Enums are strictly limited. It is impossible to define an enum value outside of the specified values (whereas with a class you can invoke new to create a new value).

Enums are also heavily optimized by at least most JVMs, and there are also new classes and language features which take advantage of enums' compactness and speed. For example, there are new classes created, EnumSet and EnumMap, which implement an enum-keyed set or map using a bitset and an array, respectively (which are probably the fastest possible implementations for those abstract data types).

Additionally, enum types can be used in switch statements. If you're pre-Java1.7, this is your best option for customized switch statements (and is still probably superior to using String values because of type safety; mistyping the enum value will cause a compile-time error, but mistyping the string will cause a more insidious runtime error-- or worse, a logic error that you can't understand until you really stare at the code and see the typo).

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
6

An enum has a number of features that plains classes don't have.

  • They have a fixed number of instances which you define in one place.
  • They can be used in switch statements.
  • obtain a complete list of enums
  • lookup an enum from its strings.
  • can get the name of an enum.
  • can sub class individual enum values.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Could you provide a link to more information about your last point ("can sub class individual enum values")? I'm curious to learn more. – Platinum Azure Aug 14 '12 at 14:11
  • Here is a good one http://www.basilv.com/psd/blog/2006/advanced-uses-of-java-5-enums and one I wrote http://vanillajava.blogspot.co.uk/2011/06/java-secret-using-enum-as-state-machine.html – Peter Lawrey Aug 14 '12 at 14:23
  • Oh, I misunderstood your point. I thought you meant that you could define a class `public class MySubclass extends MyEnum.SOME_VALUE` and I was struggling to determine the use for that! :-) I am aware of being able to override methods in individual instances, though. That's way cool. – Platinum Azure Aug 14 '12 at 14:48
  • Do that creates subclasses where getClass().getSuperclass() is the enum class. – Peter Lawrey Aug 14 '12 at 14:53
  • 1
    Yeah, that makes sense. I know that enums are quite highly abstracted syntactic sugar for existing mechanisms. – Platinum Azure Aug 14 '12 at 15:16
6

Well, actually Enum in java is just syntactical sugar for declaring a whole class hierarchy.

writing:

public enum MyEnum {
   FOO, BAR
}

is roughly equivalent to writing

public abstract class MyEnum {
    public static final MyEnum FOO = new MyEnum(){};
    public static final MyEnum BAR = new MyEnum(){};

    private MyEnum(){}
}

Which might seem overkill at first, but the you realise you can do all the things classes can do, such as:

public enum Operators {
    ADD("+"){ 
        public double apply(double lhs, double rhs){ return lhs + rhs; }
    },

    SUBTRACT("-"){ 
        public double apply(double lhs, double rhs){ return lhs - rhs; }
    },

    MULTIPLY("*"){ 
        public double apply(double lhs, double rhs){ return lhs * rhs; }
    },

    DIVIDE("/"){ 
        public double apply(double lhs, double rhs){ return lhs / rhs; }
    };

    private final String symbol;

    Operators(String symbol){
        this.symbol = symbol;
    }

    public abstract double apply(double lhs, double rhs);
}

Which is now equivalent (plus some extra convenience methods) to :

public abstract class Operators {
    public static final Operators ADD = new Operators("+"){ 
        public double apply(double lhs, double rhs){ return lhs + rhs; }
    };

    public static final Operators SUBTRACT = new Operators("-"){ 
        public double apply(double lhs, double rhs){ return lhs - rhs; }
    };

    public static final Operators MULTIPLY = new Operators("*"){ 
        public double apply(double lhs, double rhs){ return lhs * rhs; }
    },

    public static final Operators DIVIDE = new Operators("/"){ 
        public double apply(double lhs, double rhs){ return lhs / rhs; }
    };

    private final String symbol;

    private Operators(String symbol){
        this.symbol = symbol;
    }

    public abstract double apply(double lhs, double rhs);
}

Which I'm sure we can agree is much more poweful than the very basic C version. And of course, with enums it is guaranteed that each of the members of the enum is a singleton.

LordOfThePigs
  • 11,050
  • 7
  • 45
  • 69
4

Following are the reasons to use Enums -

1) Enum is type-safe you can not assign anything else other than predefined enum constant to an enum variable.

2) Enum has its own name-space.

3) Best feature of Enum is you can use Enum in Java inside Switch statement like int or char primitive data type. But In java 7 we can use String in switch statements.

4) Adding new constants on Enum in Java is easy and you can add new constants without breaking existing code.

Pramod Kumar
  • 7,914
  • 5
  • 28
  • 37
1

Enum also makes for a great singleton in Java:

http://en.wikipedia.org/wiki/Singleton_pattern#The_Enum_way

I guess this is yet another case where you could use an enum instead of a class.

bjedrzejewski
  • 2,378
  • 2
  • 25
  • 46
  • I won't agree, you still can use `nested static class` as a helper to generate a thread-safe singleton – Hearen Mar 28 '19 at 05:48
0

You use an enum if you have a fix set of values, enumerated in an ... ehhm ... enum :)

You use a class if you want any number of instances of something the class describes.

Marc
  • 1,900
  • 14
  • 22
  • 1
    With your example of difficulties: if you only ever need these 3 different difficulties an enum is perfect. If you want to read the possible difficulties from a config file, database, ... then you would model a class. – Marc Aug 14 '12 at 13:54
0

Because a class can have an arbitrary number of instances, whereas in an "enum", the number of instances is limmited to the elements of the enumeration itself (that's why the constructor has to be private), and these instances can be accessed statically.

Mr.Eddart
  • 10,050
  • 13
  • 49
  • 77