Java Shot #2: Prefer using equality operator over equals() method for enums

Enums are a powerful datatype in Java. There are many instances where you want to compare two enums. Given that a enum class supports equals() method, we end up using equals() method as it's frequently used for other object comparisons.

Even IntelliJ's AI recommendation is to use equals() method 🤭

In case of enums, using == (equality) operator is a best practice.

Why? Let's look at the below code.


class Main {
  enum NumberType {
    PRIME,
    COMPOSITE
  }

  // returns NumberType.PRIME if number is prime
  // returns NumberType.COMPOSITE if the number is composite
  // else returns null
  //
  // This method is buggy since this doesn't have any validations on the numbers.
  // You can consider this method you are using from an external library.
  static NumberType getNumberType(Integer number) {
    // function logic for prime and composite numbers.
    return null;  
  }

  public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
      // 0 and 1 and negative numbers cannot be categorised into prime or composite and hence it
      // leads to
      // NullPointerException when using equals() method.
      if (getNumberType(i).equals(NumberType.PRIME)) {
        System.out.printf("%d is composite", i);
      } else if (getNumberType(i).equals(NumberType.COMPOSITE)) {
        System.out.printf("%d is composite", i);
      } else {
        System.out.printf("%d is neither prime nor composite", i);
      }
    }
  }
}

If you execute this program, this will throw NullPointerException (NPE).

This can be easily avoided by making use of == operator.


class Main {
  enum NumberType {
    PRIME,
    COMPOSITE
  }

  // returns NumberType.PRIME if number is prime
  // returns NumberType.COMPOSITE if the number is composite
  // else returns null
  //
  // This method is buggy since this doesn't have any validations on the numbers.
  // You can consider this method you are using from an external library.
  static NumberType getNumberType(Integer number) {
    // function logic for prime and composite numbers.
    return null;
  }

  public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
      // 0 and 1 and negative numbers cannot be categorised into prime or composite and hence it
      // leads to
      // NullPointerException when using equals() method.
      if (getNumberType(i) == NumberType.PRIME) {
        System.out.printf("%d is composite\n", i);
      } else if (getNumberType(i) == NumberType.COMPOSITE) {
        System.out.printf("%d is composite\n", i);
      } else {
        System.out.printf("%d is neither prime nor composite\n", i);
      }
    }
  }
}

Why this works? For the simple reason that Enum values are singletons and they have a single reference, == works for them.

There is also a different way you can avoid NPE when using equals() method.

Can you guess the approach?