Yes, it is as if you had created singleton instances for each value in the enum:
public abstract class RoundingMode {
public static final RoundingMode HALF_UP = new RoundingMode();
public static final RoundingMode HALF_EVEN = new RoundingMode();
private RoundingMode() {
// private scope prevents any subtypes outside of this class
}
}
However, the enum
construct gives you various benefits:
- Each instance's toString() prints the name given in code.
- (As mentioned in another post,) a variable of the enum type can be compared against constants using the
switch-case
control structure.
- All the values in the enumeration can be queried using the
values
field that is 'generated' for each enum type
- Here's the big one w.r.t identity comparisons: enum values survive serialization without cloning.
The serialization is a big gotchya. If I were to use the code above instead of an enum, here's how identity equality would behave:
RoundingMode original = RoundingMode.HALF_UP;
assert (RoundingMode.HALF_UP == original); // passes
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(original);
oos.flush();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
RoundingMode deserialized = (RoundingMode) ois.readObject();
assert (RoundingMode.HALF_UP == deserialized); // fails
assert (RoundingMode.HALF_EVEN == deserialized); // fails
You can address this issue without enum, using a technique that involves writeReplace
and readResolve
, (see http://java.sun.com/j2se/1.4.2/docs/api/java/io/Serializable.html)...
I guess the point is -- Java goes out of its way to allow you use enum values' identities for testing equality; it is an encouraged practice.