深度反射比较等于

我正在尝试通过将生成的对象与原始对象进行比较来验证序列化和反序列化例程。这些例程可以序列化任意和深度嵌套的类,因此我想要一个比较例程,它可以给定原始实例和最终实例,并反射地遍历每个值类型并比较值,并迭代到引用类型以比较值。

我尝试过Apache Commons Lang EqualsBuilder.reflectionEquals(inst1,inst2),但这似乎并没有做一个非常深入的比较,它只是比较了相等的引用类型,而不是深入研究它们:

下面的代码说明了我的问题。第一个调用返回 true,但第二个调用返回 false。reflectionEquals

有没有任何人都可以推荐的图书馆例程?

class dummy {
    dummy2 nestedClass;
}

class dummy2 {
    int intVal;
}

@Test
public void testRefEqu() {

    dummy inst1 = new dummy();
    inst1.nestedClass = new dummy2();
    inst1.nestedClass.intVal = 2;
    dummy inst2 = new dummy();
    inst2.nestedClass = new dummy2();
    inst2.nestedClass.intVal = 2;
    boolean isEqual = EqualsBuilder.reflectionEquals(inst1.nestedClass, inst2.nestedClass);
    isEqual = EqualsBuilder.reflectionEquals(inst1, inst2);
}

答案 1

从这个问题的答案 https://stackoverflow.com/a/1449051/116509 和一些初步测试来看,Unitils'似乎做到了你所期望的。(编辑:但可能会被放弃,所以你可以尝试AssertJ https://assertj.github.io/doc/#assertj-core-recursive-comparisonReflectionAssert.assertReflectionEquals)

2021年编辑:现在有一个选项。但是,提到的单元测试库将为您提供更好的失败消息以帮助调试,因此根据上下文,它们仍然是最佳选择。EqualsBuildertestRecursive


答案 2

一种方法是使用反射来比较对象 - 但这很棘手。另一种策略是比较序列化对象的字节数组:

class dummy implements Serializable {
    dummy2 nestedClass;
}

class dummy2  implements Serializable {
    int intVal;
}

@Test
public void testRefEqu() throws IOException {

    dummy inst1 = new dummy();
    inst1.nestedClass = new dummy2();
    inst1.nestedClass.intVal = 2;

    dummy inst2 = new dummy();
    inst2.nestedClass = new dummy2();
    inst2.nestedClass.intVal = 2;

    boolean isEqual1 = EqualsBuilder.reflectionEquals(inst1.nestedClass, inst2.nestedClass);
    boolean isEqual2 = EqualsBuilder.reflectionEquals(inst1, inst2);

    System.out.println(isEqual1);
    System.out. println(isEqual2);

    ByteArrayOutputStream baos1 =new ByteArrayOutputStream();
    ObjectOutputStream oos1 = new ObjectOutputStream(baos1);
    oos1.writeObject(inst1);
    oos1.close();

    ByteArrayOutputStream baos2 =new ByteArrayOutputStream();
    ObjectOutputStream oos2 = new ObjectOutputStream(baos2);
    oos2.writeObject(inst1);
    oos2.close();

    byte[] arr1 = baos1.toByteArray();
    byte[] arr2 = baos2.toByteArray();

    boolean isEqual3 = Arrays.equals(arr1, arr2);

    System.out.println(isEqual3);

}

您的应用程序序列化和反序列化对象,因此此方法似乎是您的问题的最快解决方案(就 CPU 操作而言)。