In Java, an Enum can do the great things that Enums do, but can also have methods (behavior and logic). What advantage does that have over using a class using an enum? Simple examples to illustrate the point would also be welcome.
I'm not quite sure where the title of the question fits in with the rest of it. Yes, Java enums have behaviour. They can have state too, although it should really, really be immutable state. (The idea of a mutable enum value is pretty scary IMO.)
An enum in Java is a fixed set of objects, basically. The benefit is that you know that if you have a reference of that type, it's always either null
or one of the well-known set.
Personally I really love Java enums and wish C# had them too - they're much more object-oriented than C#'s enums which are basically "named numbers". There are a few "gotchas" in terms of initialization order, but they're generally fab.
In our project, we're using Enums for a few things, but perhaps most prominently for i18n purposes - each piece of shown text is given an Enum. The Enum class has a String-returning method that inspects the Locale that is being used, and picks the correct translation from a collection of translations on runtime.
This serves as a dual-purpose - you get code completion from your IDE, and also never forget to translate a string.
The usage is very simple, to the point that it's almost rendundant to give an example, but here's how one might use the translation-enum
System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());
Or, if you want to be fancy, have the Enum accept arguments, which will, with some magic string manipulation, be inserted in a marked position in the translations string
System.out.println(Translations.GREET_PERSON.trans(user.getName());
Here's a simple example:
enum RoundingMode {
UP {
public double round(double d) {
return Math.ceil(d);
}
},
DOWN {
public double round(double d) {
return Math.floor(d);
}
};
public abstract double round(double d);
}
Enum
types are also a great way to implement true singletons.
Classic singleton patterns in Java typically involve private constructors and public static factory methods but are still vulnerable to instantiation via reflection or (de-)serialization. An enum type guards against that.
Because the enum instances are singletons, you can use them in switch
statements or with ==
to check equality.
Basically, Java enums are classes (I don't believe there is a difference at the bytecode level), with the additional benefit of having a known fixed set of possible instances and being able to use them in switch statements.
You can emulate the "known fixed set of possible instances" with regular classes (the "typesafe enum" pattern described in countless books and articles), but it's quite some work (repeated for every such class) to get it to work really correctly in regard to Serialization, equals() and hashCode(), and perhaps some other things I forgot. Language-level enums spare you that work. And, as mentioned above, only language-level enums can be used in switch statements.