Why does comparing enums using == cause a PMD warning?

1k views Asked by At

The following compares two enum values using ==:

MyEnum enum1 = blah();     // could return null
MyEnum enum2 = blahblah()  // could return null
if (enum1 == enum2) {
    // ...
}

But PMD gives a CompareObjectsWithEquals warning on line 3:

Use equals() to compare object references

Not sure I understand the source code for this check but thought it was OK to compare two enums using == so am wondering whether my code could be improved or the check is incorrect.

2

There are 2 answers

0
Marvin On BEST ANSWER

This is indeed accepted as bug:

However, it seems to be tricky to catch all possible cases (quote from the newer bug):

That one is a bit tricky, as in order to determine, whether a type is a Enum, we need type resolution.

I was able to adjust the rule to check, whether the type of the variables is an Enum. This works only, if the Enum types are on the "auxclasspath" of pmd, so that the type resolution can find it.

Your example in isolation would still trigger this false positive, as PMD doesn't know what ProcessingStatus is. I verified it with java.math.RoundingMode, which is always on the classpath and will be resolved.

("Your example" refers to the ticket author, not the OP on Stack Overflow)

Your case might work with PMD 5, the source you linked belongs to PMD 4.

Update: The current source contains the additional check for enums:

 // skip, if it is an enum
 if (type0.getType() != null && type0.getType().equals(type1.getType()) && type0.getType().isEnum()) {
      return data;
 }
3
Konstantin Yovkov On

It's fine to use .equals(), because under the hoods, what happens is that the instances are compared with ==.

public final boolean equals(Object other) {
    return this==other;
}

Note that this implementation of .equals() is final, which means you cannot override it in your enum.