为什么使用“==”比较枚举会导致PMD警告?

6
以下使用==比较两个枚举值:
MyEnum enum1 = blah();     // could return null
MyEnum enum2 = blahblah()  // could return null
if (enum1 == enum2) {
    // ...
}

但是PMD在第三行发出了CompareObjectsWithEquals警告:

使用equals()比较对象引用

不确定我是否理解此检查的源代码,但是认为使用 == 比较两个枚举类型是可以的,因此想知道我的代码是否可以改进或检查是否有误。


2
可以。可能相关:http://sourceforge.net/p/pmd/bugs/1028/ - MadConan
2个回答

18

这确实被视为一个bug:

但是,捕获所有可能的情况似乎有些棘手(摘自更新的bug):

那个比较棘手,因为为了确定类型是否是枚举类型,我们需要进行类型解析。

我能够调整规则以检查变量类型是否是枚举类型。这只有在 Pmd 的“auxclasspath”上存在枚举类型时才有效,所以类型解析才可以找到它。

您单独提供的例子仍会触发此误报,因为 PMD 不知道 ProcessingStatus 是什么。我用 java.math.RoundingMode 进行验证,它始终位于 classpath 上并将被解析。

(“您的例子”指的是ticket作者,而不是Stack Overflow上的OP)

您的情况可能适用于PMD 5,您链接的源代码属于PMD 4。

更新: 当前源代码包含了对枚举类型的额外检查:

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

4

可以使用.equals(),因为在内部实现中,实例是通过==来进行比较的。

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

注意,这个.equals()方法的实现是final的,这意味着你不能在你的枚举类中覆盖它。

谢谢 - 但是任何一个枚举都可能为空,所以不想冒空指针异常的风险。 - Steve Chambers
那么你将不得不添加一个检查。或者使用Java8的Optional<T>类型。 :) - Konstantin Yovkov
6
或者坚持 enum1 == enum2 并忽略这个 PMD 警告。 - stuXnet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接