2011-09-07 84 views
6

我想比较两个Java对象而不覆盖等于方法。因为我需要在n个类中重写equals方法,所以我需要一个通用的实用方法来比较两个Java对象。比较任意两个Java对象的常用方法

东西

A a1,a2; 
B b1,b2; 
C c1,c2; 
----- 
----- 
boolean isEqual1 = new ObjectComparator().isEquals(a1 , a2); 
boolean isEqual2 = new ObjectComparator().isEquals(b1 , b2); 
boolean isEqual3 = new ObjectComparator().isEquals(c1 , c2); 

请帮我写一个共同的效用比较任何Java使用Field类对象

希望和getClass方法,我们可以实现它。请指导我。

+0

http://www.unitils.org/apidocs/org/unitils/reflectionassert/ReflectionComparator.html看看这个。 – amod

回答

9

查看Apache Commons库中的EqualsBuilder.reflectionEquals

documentation

此方法使用反射来确定如果两个对象相等

它使用AccessibleObject.setAccessible访问私人领域。这意味着如果在安全管理器下运行,如果权限设置不正确,它将引发安全异常。它也不像测试那样有效。


所以,在你的例子看起来会像:

A a1,a2; 
B b1,b2; 
C c1,c2; 
----- 
----- 
boolean isEqual1 = EqualsBuilder.reflectionEquals(a1 , a2); 
boolean isEqual2 = EqualsBuilder.reflectionEquals(b1 , b2); 
boolean isEqual3 = EqualsBuilder.reflectionEquals(c1 , c2); 
+0

非常感谢。这给了我一个开始。我需要自定义该类来添加某些功能,例如,通过比较等方式为字段添加一个扩展项。EqualsBuilder类会帮助我通过扩展该类来实现这些功能吗? –

+0

警告:根据EqualsBuilder.reflectionEquals(Object lhs,Object rhs)Javadoc“瞬态成员将不被测试”。因此,即EqualsBuilder.reflectionEquals(new Date(2),new Date(3))将返回true。更好地使用reflectionEquals(Object lhs,Object rhs,boolean testTransients)。 – machinery

2

尝试阿帕奇百科全书EqualsBuilder#reflectionEquals方法,并检查它是否符合您的需求。

+1

警告:根据EqualsBuilder.reflectionEquals(Object lhs,Object rhs)Javadoc“瞬态成员将不被测试”。因此,即EqualsBuilder.reflectionEquals(new Date(2),new Date(3))将返回true。更好地使用reflectionEquals(Object lhs,Object rhs,boolean testTransients)。 – machinery

3

这可能是你在找什么EqualsBuilder.reflectionEquals

public boolean equals(Object obj) { 
    return EqualsBuilder.reflectionEquals(this, obj); 
} 
+0

* [...]不覆盖equals方法[*] *(+1;无论如何;-) – aioobe

+0

它是您可以在不覆盖的情况下调用的文档示例。 ;) –

+1

警告:根据EqualsBuilder.reflectionEquals(Object lhs,Object rhs)Javadoc“瞬态成员将不被测试”。因此,即EqualsBuilder.reflectionEquals(new Date(2),new Date(3))将返回true。更好地使用reflectionEquals(Object lhs,Object rhs,boolean testTransients)。 – machinery

1

首先,是否有令人信服的理由,你不希望使用equals方法?等值方法由集合类内部使用,因此您必须遵守等价合约。

如果有一个,那么是的,你可以使用反射来进行字段比较。 获取该类的list of fields和每个字段check the value。你还必须确保他们都是同类的前期实例。

+1

令人信服的原因是我的班级可能会增加更多的领域。每次我都需要更新equals方法。 –

0

你想Objects.equals(a,b)提供的Java 1.7,在java.util

如果您使用的不是Java 1.7更早的版本,你可以使用图书馆之一,其他人建议,最显着的Apache Commons项目。

+3

你的意思是Objects.deepEquals(a,b)。 Objects.equals(a,b)仅使用对象的默认equals()实现,但可以处理空值。 – Asturio

0

你可能要考虑使用Shazamcrest

从他们的GitHub页面:

有一个Person豆结构如下:

Person person 
    |-- String name 
    |-- String surname 
    |-- Address address 
     |-- String streetName 
     |-- int streetNumber 
     |-- String postcode 

比较两个Person豆Shazamcrest可以这样写:

assertThat(actualPerson, sameBeanAs(expectedPerson)); 
0

试试这个。这很好,但如果你比较的对象很大,需要更多的堆空间。 org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals(OBJ1,OBJ2)

http://www.unitils.org/

你可以从下面得到的罐子。

<!-- https://mvnrepository.com/artifact/org.unitils/unitils --> 
     <dependency> 
      <groupId>org.unitils</groupId> 
      <artifactId>unitils</artifactId> 
      <version>2.2</version> 
     </dependency>