是否有任何工具可以警告我不要使用以下类型的代码:
if ( someClass.equals( someString ))
例如:
if ( myObject.getClass().equals( myClassName ))
这样的事情是合法的Java(equals接受一个Object)但永远不会评估为true(一个类永远不能等于一个String)所以几乎肯定是一个bug。
我检查过Eclipse,FindBugs和PMD,但似乎没有人支持此功能?
答案 0 :(得分:8)
是的, IntelliJ IDEA 进行了这样的检查,我相信默认情况下已启用。它标记以下内容:
Class<?> clazz = String.class;
if (clazz.equals("foo")) {
//...
}
警告:
不可逆类型的对象之间的'等于()'。
可以通过设置 - &gt;项目设置 - &gt;检查启用/禁用检查,然后在可能的错误下检查/取消选中“不可转换类型的对象之间的''等于()”。“
FindBugs 也应该通过"EC: Call to equals() comparing different types"错误检查来识别它。它可以与Eclipse集成,因为您可能已经知道了。
虽然也没有银弹;他们无法读懂你的想法。你可以期待的最好的是它会有利于误报,而不是假阴性。
答案 1 :(得分:1)
您要检查的内容不一定是“问题”:equals()
类中声明了Object
,并将Object
作为参数。类覆盖这个方法,它们的实现可能允许不同类的对象“等于”目标对象。
我自己已经做了几次,例如,如果另一个对象(比如String)与目标的键字段匹配,则允许对象“等于”另一个对象:
class MyClass {
private String id;
public boolean equals(Object obj) {
// Compare as if "this" is the id field
return id.equals(obj instanceof MyClass ? ((MyClass)obj).id : obj);
}
public int hashCode() {
return id.hashCode(); // so hashCode() agrees with equals()
}
}
它实际上非常方便,因为以下代码将按预期工作:
List<MyClass> list = new ArrayList<MyClass>();
// collection methods will work with instances:
list.contains(someInstance);
list.remove(someInstance);
list.indexOf(someInstance);
// and with keys!
// handy if you can only get the key, for example from a web url parameter
list.contains("somekey");
list.remove("somekey");
list.indexOf("somekey");
答案 2 :(得分:1)
这是.NET中IEquatable<T>
接口背后的想法:为类型提供一种机制来实现我称之为强类型的相等性。还有IEqualityComparer<T>
接口,允许以单独的类型实现此逻辑。
根据this StackOverflow question(Jon Skeet的回答,他通常似乎知道他在说什么),在Java中似乎没有任何等价物。
当然,你总是可以自己为自己的类型实现这样的东西,但是对于作为Java基类库一部分的类型,它不会对你有很大帮助。对于此类问题的编译时检测,最好的选择是某种分析工具(Mark Peters indicates显然有一个内置于IntelliJ IDEA中)可以向您建议某些代码可能要怀疑。一般来说,假设你不是一个不理会警告的人,这应该足够好了。