我已经厌倦了为我的所有类重写Object.equals,所以我提出了这个重写方法,如果在项目的所有类中使用,它会产生所需的结果。
@Override
public boolean equals(Object anObject){
if (this == anObject) {
return true;
}
//same class?
if (anObject.getClass() == this.getClass()) {
Field[] fields = this.getClass().getFields();
boolean fieldsEqual = true;
for (Field field : fields) {
try {
fieldsEqual &=
field.get(anObject).equals(field.get(this));
} catch (IllegalAccessException e) { }
}
//if fields equal, objects are equal.
return fieldsEqual;
}
//not the same class, so the objects aren't equal
return false;
}
这样安全吗?未处理的IllegalAccessException
让我有点担心,但鉴于该方法首先检查this
和anObject
是否是同一个类,我不认为除非字段是在运行时期间从类中动态删除或添加。看起来这可能是一个非常方便的代码片段,如果除了那个例外它是安全的。
StackOverflow的专业人士在想什么?
答案 0 :(得分:2)
我不认为尝试/捕获吞噬IllegalAccessException是一个好主意,这可能会导致你调试一个非常毛茸茸的bug,我会记录某个地方。
我通常使用ApacheCommons equals method作为equals()。
答案 1 :(得分:1)
这真是一个非常糟糕的主意。
请让IDE为您生成hashCode()
和equals()
,或者使用库,即Apache Commons Lang EqualsBuilder,如@Louis Wasserman建议的那样。
除了性能不佳以及当字段为NullPointerException
时抛出null
(如评论中所述),您的代码可能会遇到无限循环:
public static class Test {
static class ClassWithUnsafeEqualsMethod {
@Override
public boolean equals(Object anObject){
if (this == anObject) {
return true;
}
//same class?
if (anObject.getClass() == this.getClass()) {
Field[] fields = this.getClass().getFields();
boolean fieldsEqual = true;
for (Field field : fields) {
try {
fieldsEqual &=
field.get(anObject).equals(field.get(this));
} catch (IllegalAccessException e) { }
}
//if fields equal, objects are equal.
return fieldsEqual;
}
//not the same class, so the objects aren't equal
return false;
}
}
static class A extends ClassWithUnsafeEqualsMethod {
B fieldB;
}
static class B extends ClassWithUnsafeEqualsMethod {
A fieldA;
}
public static void main(String... args) {
A a1 = new A();
A a2 = new A();
B b1 = new B();
B b2 = new B();
a1.fieldB = b2;
b2.fieldA = a1;
a2.fieldB = b1;
b1.fieldA = a2;
System.out.println(a1.equals(a2));
}
}
你有一个很好的java.lang.StackOverflowError
。试试吧!