In Java prior to JDK1.5, the "Typesafe Enum" pattern was the usual way to implement a type that can only take a finite number of values:
public class Suit {
private final String name;
public static final Suit CLUBS =new Suit("clubs");
public static final Suit DIAMONDS =new Suit("diamonds");
public static final Suit HEARTS =new Suit("hearts");
public static final Suit SPADES =new Suit("spades");
private Suit(String name){
this.name =name;
}
public String toString(){
return name;
}
}
(see e.g. Item 21 from Bloch's Effective Java).
Now in JDK1.5+, the "official" way is obviously to use enum
:
public enum Suit {
CLUBS("clubs"), DIAMONDS("diamonds"), HEARTS("hearts"), SPADES("spades");
private final String name;
private Suit(String name) {
this.name = name;
}
}
Obviously, the syntax is a bit nicer and more concise (no need to explicitly define fields for the values, suitable toString()
provided), but so far enum
looks very much like the Typesafe Enum pattern.
Other differences I am aware of:
values()
methodswitch()
(and the compiler even checks that you don't forget a value)But this all looks like little more than syntactic sugar, with even a few limitations thrown in (e.g. enum
always inherits from java.lang.Enum
, and cannot be subclassed).
Are there other, more fundamental benefits that enum
provides that could not be realized with the Typesafe Enum pattern?
The benefits of using enumerations include: Reduces errors caused by transposing or mistyping numbers. Makes it easy to change values in the future. Makes code easier to read, which means it is less likely that errors will creep into it.
The enums are type-safe means that an enum has its own namespace, we can't assign any other value other than specified in enum constants. Typesafe enums are introduced in Java 1.5 Version. Additionally, an enum is a reference type, which means that it behaves more like a class or an interface.
You can use enum types any time you need to represent a fixed set of constants . You can use enums when a variable (especially a method parameter) can only take one out of a small set of possible values. Examples would be things like days in a Week(Sunday, Monday etc..), or Directions (NORTH, SOUTH, EAST and WEST).
Java enums are more powerful than C/C++ enums. In Java, we can also add variables, methods, and constructors to it. The main objective of enum is to define our own data types(Enumerated Data Types). Declaration of enum in Java: Enum declaration can be done outside a Class or inside a Class but not inside a Method.
enum
and no more!enum
correctly handles serialization. You can do that with type-safe enums as well, but it's often forgotten (or simply not known). This ensures that e1.equals(e2)
always implies e1 == e2
for any two enum
values e1
and e2
(and vice versa, which is probably more important).EnumSet
and EnumMap
(stolen from this answer)Of course there are lots of advantages other people will mention here as answers. Most importantly, you can write enums
very fast and they do a lot of things like implement Serializable
, Comparable
, equals()
, toString()
, hashCode()
, etc, which you didn't include in your enum.
But I can show you a serious drawback of enum
(IMO). Not only can't you subclass them at will, but you can't equip them with a generic parameter. When you could write this:
// A model class for SQL data types and their mapping to Java types public class DataType<T> { private final String name; private final Class<T> type; public static final DataType<Integer> INT = new DataType<Integer>("int", Integer.class); public static final DataType<Integer> INT4 = new DataType<Integer>("int4", Integer.class); public static final DataType<Integer> INTEGER = new DataType<Integer>("integer", Integer.class); public static final DataType<Long> BIGINT = new DataType<Long>("bigint", Long.class); private DataType(String name, Class<T> type){ this.name = name; this.type = type; } // Returns T. I find this often very useful! public T parse(String string) throws Exception { // [...] } } class Utility { // Enums equipped with generic types... public static <T> T doStuff(DataType<T> type) { return ... } }
This is not possible with an enum:
// This can't be done public enum DataType<T> { // Neither can this... INT<Integer>("int", Integer.class), INT4<Integer>("int4", Integer.class), // [...] }
Now in JDK1.5+, the "official" way is obviously to use
enum
:public enum Suit { CLUBS("clubs"), DIAMONDS("diamonds"), HEARTS("hearts"), SPADES("spades"); private final String name; private Suit(String name) { this.name = name; } }
Actually, it's more like
public enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES;
}
because enums already provide a name()
method. Additionally, they provide an ordinal()
method (which enables efficient data structures like EnumSet
and EnumMap
), implement Serializable
, override toString
, provide values()
and valueOf(String name)
. They can be used in a type safe switch statement, and are singletons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With