== or equals with Java enum

When you compare objects in Java you should prefer the equals()-method to == in general. The reason is that you get reference equality (like with ==) by default but you are able to change that behaviour. You can override equals() (DO NOT FORGET TO OVERRIDE hashCode() too because otherwise you will break the general class contract) to reflect logical equality which is often what you want, e.g when comparing some string constant with user input.

With primitive types like double and int you are more or less limited to == which is fine for those immutable value types.

But what is the right thing to to with the enum type introduced in Java 5?
Since enums look like a class with methods, fields and the like you might want to use equals() instead of ==. Now this is a special case where using reference equality is actually safer and thus better than logical equality.

Above (please mind the stupid example) we can see that comparing the EState enum with an ILamp using equals() is accepted perfectly by the compiler even though the condition never can be true in practice. Using == the compiler screams and tells us that we are comparing apples with oranges.

14 thoughts on “== or equals with Java enum”

  1. In the case of enum the equals method is overridden and internally it does == reference comparison. I think its better to always follow the standard of using .equals comparison in this case also since internally the equals method in the ENUM class is actuall doing == reference check.

  2. @ SteveC: there shall not be any NPE when you do if ( Estate.ON.equals(lamp) ). There may be one if you’d write this as if ( lamp.equals(Estate.ON) ) but that’s not the usual way to write such tests.

  3. I think the type checking outweighs the “consistency” thing, plus it’s just cleaner looking.

    That said, prefixing with “E” is just gross looking.

    1. Hi Dave,
      nice to see you around. We are constant readers of your blog.
      The E-prefix is a bad habit we caught when Eclipse plugin programming entered our lifes. We even dreamt of leading “I”s for every interface. Shortly after, apple invented the i-prefix. We are still recovering from this trauma.

  4. I agree with bluez25 – there is a standard of doing things in Java and you should try to follow it.

    The choice between == and equals is a matter of abstraction you work with – if in a given part of code if trough method typing you can be sure that compared objects are both of the same enum type you could go for ==. I personally would not have a problem with code like:

    if (month == Months.JANUARY) {…}

  5. == and equals are different operations for different purposes. There is no “prefer this over that”, just “what is right”.

    In case of enums one wants to check if the given enum is another enum (which are singletons). No doubt == is the operation to choose.

    (This leaves next to none purpose for the equals method in enums. Caused by the chosen and late implementation of enums.)

  6. What if, for some abominable reason, you write a mutable enumeration? I think for the sake of defensive programming, you should implement equals().

    1. I think you should not write a mutable enumeration in the first place. It is counter-intuitive and will eventually lead to much confusion for every new dev that tries to understand the code. Besides using == would continue to work because the enums are essientially singletons and two references to Month.AUGUST would point to the very same object which thus would have the same mutable state that you could use in an equals() comparison. I cannot imagine a sane case where two *different* enums should be considered equal.

  7. I find it’s fine to compare enum types using ==. actually it’s always same result as equals(). I am thinking, the enum constants are something similar to public static object variables of its own type.

    1. You are completely right here. Java enums are actually syntactic sugar for Bloch’s “typesafe enum pattern” presented in the Java 1.4 version of his excellent book “Effective Java”.

    1. The point is that the compiler can guard you against comparing apples to oranges. You are right that is does not matter performance-wise.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.