Java依赖对象序列化一致性

时间:2018-05-21 20:23:16

标签: java serialization

我有包含Address的Employee,两者都是可序列化的。但是当我进行序列化测试时它失败我看到该地址有不同的ID

序列化:地址@ 6adca536反序列化:地址@ 6b143ee9 我不确定是否需要实现自己的序列化。

public class EmployeeTestU extends BaseUnitTest {

    private Employee employee;
    private Address address

    @Before
    public void setUp() {
        employee = new Employee();
        employee.setName("Foo:);
        employee.setId(1l);
        Address address = new Address();
        address.setPincode("23433");
        address.setArea("testArea");
        List<Address> addressList = new ArrayList<>();
        addressList.add(address);
        employee.setAddress(addressList);
    }




    @Test
    public void testConsistency() throws IOException, CloneNotSupportedException, ClassNotFoundException{
        byte[] serialized1 = serialize(employee);
        byte[] serialized2 = serialize(employee);

        Object deserialized1 = deserialize(serialized1);
        Assert.assertEquals(employee, deserialized1);
    }

public class Employee implements Serializable {

        private static final long serialVersionUID = -5991582870430548008L;

        private Long id;

        private List<Address> addresses;

        private String  name;

        public Employee() {
        }
        //getter setter and default consutructor

    }

public class Address implements Serializable{

    private static final long serialVersionUID = -5991582870430548008L;
    private String pincode;

    private String area;
    private String state;
    //getter setter and default consutructor

}

2 个答案:

答案 0 :(得分:1)

Assert.assertEquals(Object, Object)使用Object.equals方法测试相等性。

您的序列化正在运行。关于默认Object.equals方法的假设是什么。

默认Object.equals将比较对象的引用,而不是对象的状态。因为反序列化实际上是一个对象的构造,所以......

byte[] serialized1 = serialize(employee);
Object deserialized1 = deserialize(serialized1);

...创建一个新对象。 deserialized1不是employee:它是通过反序列化新创建的对象。这个新对象有另一个引用,测试失败。

按照@Ivan的建议覆盖并实施Object.equalsObject.hashCode

答案 1 :(得分:0)

从此链接:https://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()

  

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)

所以你有两个不同的对象(不同意思是它们位于内存中的不同位置),这就是hashCode()的默认实现返回不同值的原因。您可以检查初始对象和已还原对象之间的属性值,以查看它们是否相同。

为了能够使用Assert.assertEquals(),您需要覆盖班级中的equals()(覆盖hashCode()时最好覆盖equals()