SO上有两个类似的问题:
Is there a Java reflection utility to do a deep comparison of two objects?
Deep reflective compare equals
但是,很有趣,他们都没有给出完全正确的答案。
我和其他问题的作者真正想要的是,某些库中的一些方法只会告诉两个对象是否相等:
boolean deepEquals(Object obj1, Object obj2)
即。没有抛出任何例外,等等。
apache
的{{1}}不是这样,因为它没有深入比较。
EqualsBuilder
似乎也是错误的决定,因为它的方法不会返回Unitils
或true
;如果比较失败,它只会引发异常。当然,它可以像这样使用:
false
但它似乎非常难看,Difference difference = ReflectionComparatorFactory.createRefectionComparator(new ReflectionComparatorMode[]{ReflectionComparatorMode.LENIENT_ORDER, ReflectionComparatorMode.IGNORE_DEFAULTS}).getDifference(oldObject, newObject);
库似乎对于所需的比较目的而言似乎太难了。
此外,很清楚如何通过self创建这样的unitils
,但是不太可能没有包含已经实现的方法的常用库。有什么想法吗?
答案 0 :(得分:2)
Java 1.7有Objects.deepEquals(Object a, Object b)
不幸的是,Unitils
的{{1}}类没有附带方法返回ReflectionAssert
或true
。你可以尝试:
https://github.com/jdereg/java-util
其false
班级有DeepEquals
和DeepEquals.deepEquals(Object a, Object b)
个方法,您可以使用这些方法覆盖班级的DeepEquals.deepHashCode(Object o)
和equals
方法,或在外部使用hashCode
1}}或Comparator
。
注意:此DeepEquals实现有一个限制。如果类具有用户定义的重写等于方法,那将优先。
答案 1 :(得分:2)
我不认为Apache EqualsBuilder
是一个可怕的答案,但是对于一个能够做你想要的简单界面,你需要稍微包装一下。这是一个例子。
public static <T> boolean matches(T actual, T expected, String... excludedFields) {
assert actual != null;
assert expected != null;
boolean matches = EqualsBuilder.reflectionEquals(actual, expected,
false /* testTransients */,
null /* reflectUpToClass */,
true /* testRecursive */,
excludedFields);
if (!matches) {
log.warn("Actual result doesn't match.");
logComparison(actual, expected);
}
return matches;
}
public static <T> void logComparison(T actual, T expected) {
//Making sure hashcodes don't thrown an exception
assert actual.hashCode() > Integer.MIN_VALUE;
assert expected.hashCode() > Integer.MIN_VALUE;
log.warn("Expected: \n" + reflectionToString(expected));
log.warn("Actual: \n" + reflectionToString(actual));
}