Java version 1.5 or later has built-in support for
enumerated types. Prior to that you had to kludge them in some way with static
final ints (which were not typesafe) or with Objects which would not work in switch
enum with the Enumeration
interface, an almost obsolete way of iterating over Collections, replaced by
Java version 1.5
enums are references to a fixed set of Objects than represent the various possible choices. enums handle single choices, not combinations of choices. For
combinations, you need EnumSet. For HashMap-style
lookups when the key in an enum, you need EnumMap.
Enum and the enum
constants are just classes. Since enum constants are
constants, normally they should be all capitalised. However, since the constant name
is the same as what is displayed externally, some people relax that rule and name
constants with upper or lower case names as appropriate for the application. Note
that you can’t call your enums default or null since these are
reserved words. Try usual or none.
enums you want widely known should be put in the
their own source file and given the attribute public.
You then import the enum, as you would any other
Needless to say, enums are type safe. If you try to
store an enum constant for a dog Breed into a Locomotive type enum variable, the compiler will refuse.
Sample Code using enum
The advantages of enums over an array of Strings are:
- You can use enums as case labels.
- Methods come built-in with enums to do things like
convert enums names to ordinals, and combos with
- You can attach additional fields and code to enum
- enums are type safe. With Strings all your items
in all categories are the same type. There is nothing to stop you from feeding a
fruit category to an animal parameter.
- You can compare enums quickly with ==. You don’t need to use equals as you do with String.
The disadvantages of
enums over an array of Strings are:
- You can’t create new enum constants at run
time. You must recompile. In contrast, it is easy to add another String to an array or ArrayList.
- You generate an entire new class for each enum
group and each enum option.
- You can’t create derived enum classes with a
few extra enum constants or with a few suppressed.
In contrast, you can fairly easily add a
few more Strings to a List.
- Even though under the hood, an enum is just a
class, you can’t mix generics with enums.
Further, you can’t extend them.
- You can have your enums implement a common interface, but they cannot extend
a common abstract class.
- You can’t use constants defined in the enum class
as arguments to the enum constructors. The static finals must come from
some other class, perhaps a nested static.
- Be very careful using variables in enum constant
constructors. The values must be defined at the time the class is loaded. Sometimes
the enum class gets loaded before you expect and those
values will be undefined or out of date. The precise time a class gets loaded is
often ill-defined or easily jarred.
enum Constants Can Have Common
In this simple example, the enum constants each have
an instance field colours and an instance method
enums are rather limited in use of inheritance.
- An enum cannot extend another enum.
- An enum cannot extend a class.
- An enum can implement an interface.
- An enum can contain an abstract method which is implemented by the enum constants.
To & From Ordinal
Breed dog = Breed.LABRADOR;
int ordinal = dog.ordinal();
int ordinal = 2;
Breed dog = Breed.values()[ ordinal ];
You cannot directly compare enum constant or variables. You must compare their corresponding ordinals, e.g.:
boolean greater = Breed.DALMATIAN > Breed.DACHSHUND;
boolean greater = Breed.DALMATIAN.ordinal() > Breed.DACHSHUND.ordinal();
All enums and
enum constants have some built-in methods:
Scope of enum Variables
enums can have static
variables shared between all enum constants and instance
variables. Nested enums can access the static final constants and static
variables of the enclosing class, but not its instance variables. static and instance methods behave similarly. Implicitly, a nested
enum is a nested static
class. Here is an example to demonstrate these rules:
You cannot place static final
constants ahead of your enum definitions. Neither can
you place them afterwards and use the values of those static
finals in your enum definitions. You have to
place them in some other class.
You sort an array of enum values the same way you
would an array of Object of some particular class. By default, Java sorts by ordinal.
You can define your own Comparators as in this
You can of course also sort Collections of
enums in the obvious way. I have not figured out how to
implement Comparable with enums, but even if I could, it would probably not be wise to
override the default. It would just confuse people reading the code.
enum Constants Can Have
There are three basic ways to write a method for use by an
The individual enum constants with methods are
implemented as and behave like little anonymous classes. That is how the individual
methods can override methods common to the enum as a
whole, and how the enum methods have access to the
fields of the enum as a whole as well as their own
fields. Further, the scope rules of visibility and how the scope modifiers such as
public and private work the
same way as for anonymous inner classes.
- Single common method for all enum constants. It
works with different constants passed in the constructor. The method is part of
your enum class as a whole.
- An abstract or default method in the enum class as a whole, and each enum
constant overrides it.
- enum constants have peculiar methods all their
own. If two enum constants implement the same method,
they are only incidentally related.
Keying enums in a
GUI (Graphic User Interface)
Here is how to let the user select an enum in a
enum constants can even
each have their own little anonymous inner class complete with constructors, methods
and variables. See the Under the Hood (3) example below.
I use enums for writing the finite state automata
that colourise all the listings on my website. Each state is represented by one
enum constant. Each enum
constant has custom logic to figure out the next state. The enum as a whole has both static and instance methods, and the
enum constants override some of the instance methods.
That allows a default implementation for a method that all enum constants must implement. I can invoke the method by the common
base name, just as with classes and subclasses.
It is easiest to use public or top-level enums. Begin
your experiments with public enums in their own *.java file to avoid
frustration. I have managed to get nested static
enums and nested inner enums to work as well, at least for the simple case where the
enum constants have no constructors or individual
classes. Even when you don’t specify static,
nested enum classes are considered static. They don’t require an associated outer class object.
There are no such thing as anonymous enums, and if there
were, they would not be very useful since their enum
constants would be anonymous too.
Unlike most of Java, you need to understand how enums
work under the hood. When you understand the inner class structure, everything makes
sense. Without that understanding enums will drive you
insane with bizarre behaviour and restrictions.
You cannot define static finals in an enum and use them in the
enum constructors. You can put them in a separate
private static nested class or a separate class. I find it works best to put nothing but
such static finals
in the auxiliary class.
You cannot put references to the enums in your separate class of static finals.
They need to go in the main enum class, after the enum constants.
Initialisation must proceed in this order:
- Evaluate the static finals referenced in the enum constructors.
- Evaluate the enum constructors.
- Evaluate the static finals that reference the enum constants.
An enum is a species of class, so it can be a public class, a top level default class or a nested static class. Inner class enums are
considered static even if you don’t use the
static keyword. An enum
follows the same scope and visibility rules as any other class.
I recommend using only public enums and putting them each one in its own *.java file. However, you can also create toplevel enums, and static enums like this:
All enums support both static and instance fields and methods of the enum as a whole. However, enum
constants are fields that point to unique objects of the enum class with optional anonymous inner classes. They can thus
include instance fields and methods, but not static,
simply because for some idiotic reason all inner classes can’t support
static fields and methods. Some believe the reason
statics are not implemented was not laziness but rather a desire prevent programmers
from using inner classes for purposes other than serving the outer class. One
speculated the problem comes because there are actually two flavours of anonymous
classes, those declared in a static and an instance context. Another explanation is
that you run into chicken and egg initialisation problems if you allow static members.
Under The Hood (1)
Here is a simple
program using enums and a switch. I have provided a commented decompilation so that you can
see how enum pulls off its magic.
Here is a decompilation of the above code. Note how the Breed enum is, underneath, just an
ordinary class that extends the abstract class
java.lang.Enum I wondered
wonder why Sun didn’t just use the enum ordinals
directly as case numbers. The tableswitch
JVM (Java Virtual Machine)
instruction does an indexed lookup, which would be one level of indirection less than
Oracle’s enum scheme. Perhaps Sun was worried the
compiler would sometimes generate a slower lookupswitch if
the table were not dense or if it were large. With their preconditioning, they
guarantee the table is both small and dense, which guarantees that the faster
tableswitch instruction will be used. Sun could refine
its technique by collapsing the lookupswitch table
further by using the same case number for multiple case labels on the same code.
Others have pointed out Oracle’s indirect scheme provides additional binary
compatibility. If class A has a switch statement involving enum
B, and B acquires a new
enum constant, even one in the middle of the enumeration
order, and A is not recompiled, the switch will still work (treating the new enum constant as part of the default
Under The Hood (2)
Here is a simple
program using enum where the enum constants all use the same implementation of the same method
and same instance field. I have provided a commented decompilation so that you can
see how enum pulls off its magic.
Under The Hood (3)
Here is a simple
program using enum where the one enum constant implements a method that the other enum constants do not. I have provided a commented decompilation so
that you can see how enum pulls off its magic.
What if you had three enum classes that shared a lot of identical code. How could you encapsulate it to avoid the repetition?
- Enums cannot extend other enums, so that approach will not work.
- Enums can implement an interface. That will help keep them similar, but not identical.
- I have read that in Java 1.8+ that it is possible to have implementations in interfaces. That might be the way to go.
- I don’t think enums can extend an abstract class. Even if they could, it would not ensure the code were identical, just similar.
- I have not yet experimented to see if enums can extend a class. You could put your implementation in a base class.
- Move the shared logic into a utility class (i.e. static methods)
- Move the shared logic into a dedicated type and use instances of
this type as delegate in your enums.
- Reconsider if enums are the right choice. If you
have a lot of common logic shared between different types of enums,
that’s an indication that enums are a poor fit for the underlying problem.
Enums can be
serialized. The usual serialization process would not be sufficient since it would
result in an enum variable being reconstituted to point
to a clone of the enum constant from the source machine
rather than to the corresponding enum constant in the
target machine. The serialization process gets around this problem by serializing as
the enum constant name (a String), along with information identifying its base enum type. Deserialization behaviour differs as well — the
class information is used to find the appropriate enum
class, and the Enum. valueOf
method is called with that class and the received constant name in order to obtain
the enum constant to return.
This technique makes serialized files more stable that had it been based on using
ordinals to represent the value. With Oracle’s technique you can add new
enum constants, or change the enum methods, and you can still read old serialized files with new
Other ways of externalising enums for serialization
or storing in files and databases include:
- Converting them to integer ordinals. These are extremely
compact. One byte can encode 256 different possibilities.
The problem is, if you add, delete, modify or reorder your enums, you have to write code to convert your existing
files/databases. You convert them back to enums with
- Converting them to upper case enum
names These are Strings. They are
somewhat bulkier that other methods. External files don’t usually need
updating if you add or reorder your enums. You convert
them back to enums with valueOf.
- Converting them to lower case letters. These are compact, a
8 or 16 bits each. Normally you
don’t have to modify your external files when your enums changes. It makes the external files a little easier to
decode. You convert them back to enums with a
switch statement. The scheme falls apart if you have a
large number of possibilities, and many enums
naturally map to the same letter.
- Save them in SQL (Standard Query Language)
enum format. This will be some proprietary format used by your
database engine. Typically you can’t modify the enum without changing the enum code
both in your database, and in your programs, and by writing a program to update
your existing tables to the new scheme. Typically you get the disadvantages of
inflexibility combined with the disadvantages of fluffy storage.
The Good About enums
- enums are much more powerful the C++ enum. It is a whole new way
of writing code.
- enums are type safe.
- You don’t have to manually assign ordinals. They are self-numbering.
- The external form is usually a String rather than a
number. This means even if your ordinals change, your old data files are still
- enums save you typing the class name on the
enum constant as case labels.
- enums let you consolidate all facts about each
enum constant in one place. As you add methods to your
enums, most of your ugly switch code disappears. This encapsulation makes code easier to
maintain, and makes the client code that uses your enum simpler.
- enums are flexible. They are like classes with the
extra wrinkles of an automatic ordinal and valueOf method.
- Let us say you had 10 static variables to
count various things, and you display the results at the end. You may find that
making each an enum with a count field, an incrementCount and a
getCount method, your code simplifies and admits adding
new features to each enum constant easily, e.g. a
description field. The code will me more maintainable. It will be trivially easy to
add another counter.
- enums can have a main
method, usually a debugging test harness.
The Bad About enums
- Even when an enum is nested in a class, you cannot
access the instance variables of the containing class. You have to communicate
instance information from the enclosing class via parameters passed to enum instance or static methods.
Implicitly a nested enum is a nested static class, so this is what you would expect.
- Unlike using simple ints for your enum logic, everything goes into its own separate enum class. This makes accessing surrounding class methods and
variables somewhat more awkward.
- enums don’t nest with inheritance. You
can’t extend an enum. You can’t extend
an enum to either add more enum constants or more static
methods or more instance methods on the enum
constants, or more instance datafields on each enum
constant, or a more elaborate constructor. There is no way to extend an
enum with fewer enum
constants. Here are a couple of kludges to extend enums.
- Pass an enum constant delegate of the base
enum to the constructor for the corresponding
enum in the extension. Then use wrappers to make
all the methods of the base enum available in your
new enum. You can see this technique used in the
- Don’t use enums at all, but instead
create an Item class and instantiate an array of
such Items each with custom values in the
constructor. These behave somewhat like enums,
except they don’t work in switch statements. You can extend the
Item class, create new Items, create subsets of existing Collections, iterate over all Items in a Collection etc.
- The expressions in your enum constant constructors
all must have values known at the time the enum class
is loaded. In traditional coding, those values don’t need to be known until
the methods are evaluated.
- In the simple case, an enum is a class derived
from Enum (capital e), with a set of static final objects of that same
class, one for each choice possibility. In a more complex case, each enum constant object could be instantiated from a different
subclass derived from the your base class common to all the constant objects, each
constant object with its own private variables and methods. The structure boggles
the mind. You need to re-learn the class/instance/reference model all over in
- It is confusing with all these enum and
enum constant instances, just how many objects there
are, and which fields are shared with which other objects. The underlying class
structure is somewhat hidden.
- The biggest problem I have found is when you declare your enum class inside another class, it becomes an ordinary anonymous
inner class, and thus you cannot have static fields in
your enum constant anonymous classes or but you can in
the enum itself. However, these enum statics are not much use since you can’t access them in the
constructor. Here is a workaround, suggested by Piotr Kobzda.
describes yet another work around.
- You are not allowed to access any static fields
anywhere in your custom enum constant constructors.
Why? I don’t know. This is a real annoyance if you want constructors to build
lists accessible to all the enum constants, such as
lists of aliases.
- enum constructors cannot access the enum static fields. However, they
can invoke the enum’s static methods that access the static fields. The problem is static initialisation has not been done at the time the
enum constructor constant constructors are invoked,
so using static methods will just see zeros.
Constructors can also directly access static final
in-lineable constants known at compile time. I asked, why does not Java just do
the static initialisation before running the
enum constant constructors? The problem then would
be the static initialisation code would not be able
to reference the enum constants. You have an
intractable chicken and egg problem. The
describes some work arounds. One work around
is to keep your enum constructor very simple and do
your initialisation later with an explicit static
- Older IDEs (Integrated Development Environments)
don’t understand the enum syntax. It confuses
them and screws up your usual ability to tidy, look up references etc.
- The implementation was driven by the desire for making no changes to the 1.4
JVM. This means
they are slower and kludgier than they could have been. I would have preferred a
direct switch lookup rather than the two-stage one
- You have to deal specially everywhere with the possibility of a null value. It is not a legitimate case label and it does not
count as a possibility for routing to default. With
ints, int choice = 0; is just another case. Under the hood the
has to check for null and throw a NullPointerException just before every enum switch.
- the assignment of ordinals to enums depends on the
order you declare them. Many IDEs
will reorder code, thus possibly breaking applications. Your datafiles might
contain embedded ordinals which will no longer map to the same enum. So you should use short names to represent enum values databases or permanently assigned numbers, just the
way you did back in the days of C++.
- Though you can write methods peculiar to a given enum constant, you can’t invoke them. You can only use them
within the enum inner class.
- You can’t declare a variable to be of the same type as some enum constant. Their class names are anonymous. The names of the
enum constants are references, not classes. This is a
Good Thing™. Otherwise you would have an explosion of classes, one for every
- Because you must put your static finals for an
enum at the end, you can’t use them in invoking
the constructors for the enum constants. You have to
put them in some other class.
- valueOf supports only one name (without aliases)
for the external Strings to represent each enum constant enum, and it must
exactly match the interval variable name, usually all caps. Normally, you want at
least both upper and lower case variants, and perhaps a few aliases to be
forgiving. You also want short names (one or two chars for databases) and long
names for humans, and localised names. If you want any of this, you must roll it
- You can’t have forward references to enum
constants. So, for example, you can pass enum
constants that are defined later, as parameters to enum constructors to create interrelationships between
Here is a simplified version of a program that lets
you create a valueOf that accepts aliases
How do you deal with storing enums in databases? Here are ways I would not
Here are ways I would recommend:
- Serializing them. Not good for long term storage, also bulky. You may not
change any of the enum constant names without
obsoleting your serialized data.
- Storing them as the program enum name, in either
upper or lower case. Bulky.
- Storing them as an internationalised String. I hope
the utter folly of this is obvious.
- Storing them as ordinals. The
fragility of ordinals is a side effect of the lack of need for explicit assignment
as you did with C++ or the old style manual Java
enums. The problem is when an enum is added or removed, it shifts all the numbers.
Any time the ordinals are disturbed, for even the tiniest change, you must
convert your database to the new numbering scheme, not just the database schema
The advantage of ordinals is they are compact, especially when you store only the
8 low order bits.
- If you delete an enum constant, the subsequent
ones will be renumbered.
- If you insert an enum constant, the subsequent
ones will be renumbered.
- If you keep the enums in alpha order they will
be reordered if any enum is renamed.
- If you ask a tidy program to clean up you enums, they will be renumbered.
- Store them as one-character ASCII (American Standard Code for Information Interchange).
You may run out of meaningful codes for large enums.
- Store them as short multi-character strings. Keeping the strings short is
important when there are millions of records containing them.
In your enum, you have a valueOf variant that accepts the database 2-char abbreviation using a
hash-map constructed at load time from values() list. The
2-char names are defined in the enum constant
constructors. This allows you to rapidly interconvert between enum ⇔ 2-char ⇔ internationalised String.
- You can use a permanent ordinal. You start out with ordinals, then as old
values are deleted, you don’t reuse the number, and you always add new ones
on the end, irrespective of what Java assigns for ordinal. You must get your
database to translate your permanent ordinals to Java ordinals with its
enum feature. This mimics the way C++ handle the problem, and makes it easy to share your
database with C++ programs.
- Store them as two-character ASCII
strings. This approach I recommend. Fixed length saves database space, as does
It is reasonably compact, and the databases don’t need to be converted when
you add or remove enums. You don’t have to run a
conversion program on a database, make sure it is run only once, or deal with what
happens if an old database is restored from backup that may need several
consecutive conversions with obsolete code. MySQL will happily interconvert these
2-character codes to your current enum ordinals or
enum names easy conversion to and from enum.
Storing invariant two-char codes in your SQL
database will protect you from the main catastrophic error — out by one on your
enum constants without noticing.
If a database contains an invalid 2-char code, you will detect the problem the
instant your code encounters it. The error won’t stealthily skulk under the
murk the way using ordinals permits.
Don’t use default in your switches. Then the compiler will notify you if you did not insert
code to handle the new enum case.
If you use Applets, your client code can convert 2-char
enums to internationalised strings. If you don’t,
then your Servlets can do it. This should be considerably
faster than getting your SQL
database to do it by table look up.
enums arrived rather late in
the game, not until Java version 1.5. By this point, most of
the Java class library was already established. This is why it so rarely uses
enums. It uses a mishmash of named int constants instead, e.g. Calendar.
Unfortunately, these have no type safety, and they are not organised into functional
groups. enums are used in some of the more recent
classes such as java.util.concurrent. TimeUnit and java.lang.annotation.
General Purpose enum
Writing general purpose code to work an arbitrary enums is quite tricky. You need to use generics deftly and play with
class objects. Part of the problem is passed parameters
cannot access the static methods of the enum as a whole. Here is an example that will select a random
enum constant from an arbitrary
Oracle’s Technote Guide on enums
Oracle’s Javadoc on Enum, the class underpinning enums
Oracle’s Javadoc on EnumMap
class : available:
Oracle’s Javadoc on Class.getEnumConstants
Oracle’s JDK Platform Guide to serializing enums
Oracle’s Javadoc on serialization form for enum
Oracle’s Javadoc on Class.getEnumConstants
Oracle’s Javadoc on EnumMap
class : available:
inner class gotchas