Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.
equals method uses == operator internally to check if two enum are equal. This means, You can compare Enum using both == and equals method.
equals() method returns true if the specified object is equal to this enum constant. Using == operator. The == operator checks the type and makes a null-safe comparison of the same type of enum constants.
Comparing String to Enum type in JavaFor comparing String to Enum type you should convert enum to string and then compare them. For that you can use toString() method or name() method. toString()- Returns the name of this enum constant, as contained in the declaration.
Just my 2 cents: Here is the code for Enum.java, as published by Sun, and part of the JDK:
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
// [...]
/**
* Returns true if the specified object is equal to this
* enum constant.
*
* @param other the object to be compared for equality with this object.
* @return true if the specified object is equal to this
* enum constant.
*/
public final boolean equals(Object other) {
return this==other;
}
}
Yes, == is fine - there's guaranteed to be just a single reference for each value.
However, there's a better way of writing your round method:
public int round(RoundingMode roundingMode) {
switch (roundingMode) {
case HALF_UP:
//do something
break;
case HALF_EVEN:
//do something
break;
// etc
}
}
An even better way of doing it is to put the functionality within the enum itself, so you could just call roundingMode.round(someValue)
. This gets to the heart of Java enums - they're object-oriented enums, unlike the "named values" found elsewhere.
EDIT: The spec isn't very clear, but section 8.9 states:
The body of an enum type may contain enum constants. An enum constant defines an instance of the enum type. An enum type has no instances other than those defined by its enum constants.
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:
switch-case
control structure.values
field that is 'generated' for each enum typeThe 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.
== compares the references of two objects. For enums, it is guaranteed that there will only be one instance, and therefore for any two enums that are the same, == will be true.
Reference:
http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks
(couldn't find anything in the Sun docs)
Here is some evil code you might find interesting. :D
public enum YesNo {YES, NO}
public static void main(String... args) throws Exception {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
YesNo yesNo = (YesNo) unsafe.allocateInstance(YesNo.class);
Field name = Enum.class.getDeclaredField("name");
name.setAccessible(true);
name.set(yesNo, "YES");
Field ordinal = Enum.class.getDeclaredField("ordinal");
ordinal.setAccessible(true);
ordinal.set(yesNo, 0);
System.out.println("yesNo " + yesNo);
System.out.println("YesNo.YES.name().equals(yesNo.name()) "+YesNo.YES.name().equals(yesNo.name()));
System.out.println("YesNo.YES.ordinal() == yesNo.ordinal() "+(YesNo.YES.ordinal() == yesNo.ordinal()));
System.out.println("YesNo.YES.equals(yesNo) "+YesNo.YES.equals(yesNo));
System.out.println("YesNo.YES == yesNo " + (YesNo.YES == yesNo));
}
Enums are a great place to jam polymorphic code.
enum Rounding {
ROUND_UP {
public int round(double n) { ...; }
},
ROUND_DOWN {
public int round(double n) { ...; }
};
public abstract int round(double n);
}
int foo(Rounding roundMethod) {
return roundMethod.round(someCalculation());
}
int bar() {
return foo(Rounding.ROUND_UP);
}
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