The only difference is that enum constants are public , static and final (unchangeable - cannot be overridden). An enum cannot be used to create objects, and it cannot extend other classes (but it can implement interfaces).
An enum type is implicitly final unless it contains at least one enum constant that has a class body. It is a compile-time error to explicitly declare an enum type to be final. Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.
Enums limit you to the required set of inputs whereas even if you use constant strings you still can use other String not part of your logic. This helps you to not make a mistake, to enter something out of the domain, while entering data and also improves the program readability.
switch
statement case
statements without qualification.ordinal().
EnumSet
and EnumMap
classes. Technically one could indeed view enums as a class with a bunch of typed constants, and this is in fact how enum constants are implemented internally. Using an enum
however gives you useful methods (Enum javadoc) that you would otherwise have to implement yourself, such as Enum.valueOf
.
Nobody mentioned the ability to use them in switch
statements; I'll throw that in as well.
This allows arbitrarily complex enums to be used in a clean way without using instanceof
, potentially confusing if
sequences, or non-string/int switching values. The canonical example is a state machine.
The primary advantage is type safety. With a set of constants, any value of the same intrinsic type could be used, introducing errors. With an enum only the applicable values can be used.
For example
public static final int SIZE_SMALL = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE = 3;
public void setSize(int newSize) { ... }
obj.setSize(15); // Compiles but likely to fail later
vs
public enum Size { SMALL, MEDIUM, LARGE };
public void setSize(Size s) { ... }
obj.setSize( ? ); // Can't even express the above example with an enum
There is less confusion. Take Font
for instance. It has a constructor that takes the name of the Font
you want, its size and its style (new Font(String, int, int)
). To this day I cannot remember if style or size goes first. If Font
had used an enum
for all of its different styles (PLAIN
, BOLD
, ITALIC
, BOLD_ITALIC
), its constructor would look like Font(String, Style, int)
, preventing any confusion. Unfortunately, enum
s weren't around when the Font
class was created, and since Java has to maintain reverse compatibility, we will always be plagued by this ambiguity.
Of course, this is just an argument for using an enum
instead of public static final
constants. Enums are also perfect for singletons and implementing default behavior while allowing for later customization (I.E. the strategy pattern). An example of the latter is java.nio.file
's OpenOption
and StandardOpenOption
: if a developer wanted to create his own non-standard OpenOption
, he could.
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