如何在Java中测试一个类正确实现Serializable(不仅仅是Serializable的一个实例)

Jas*_*n S 70 java serialization

我正在实现一个可序列化的类(所以它是一个使用w/RMI的值对象).但我需要测试它.有办法轻松做到这一点吗?

澄清:我正在实现这个类,所以在类定义中坚持使用Serializable是微不足道的.我需要手动序列化/反序列化它以查看它是否有效.

我发现了这个C#问题,Java有类似的答案吗?

ska*_*man 117

最简单的方法是检查的对象是的实例java.io.Serializable或者java.io.Externalizable,但并没有真正证明对象确实是序列化的.

唯一可靠的方法是尝试真实.最简单的测试类似于:

new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(myObject);
Run Code Online (Sandbox Code Playgroud)

并检查它不会抛出异常.

Apache Commons Lang提供了一个相当简短的版本:

SerializationUtils.serialize(myObject);
Run Code Online (Sandbox Code Playgroud)

再次,检查异常.

你可以更严格,并检查它反序列化回原来的东西:

Serializable original = ...
Serializable copy = SerializationUtils.clone(original);
assertEquals(original, copy);
Run Code Online (Sandbox Code Playgroud)

等等.

  • 即使这也不是万无一失的。如果对象具有不可序列化的字段,但它们为null,则它将可序列化;初始化它们,事实并非如此。 (4认同)
  • 以防万一有人好奇或不想包含 Apache Commons 库,Spring 也有 SerializationUtils 和方法 `serialize` 和 `deserialize`。参见 [SerializationUtils](http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/util/SerializationUtils.html) (2认同)

Jas*_*n S 25

基于skaffman答案的实用方法:

private static <T extends Serializable> byte[] pickle(T obj) 
       throws IOException 
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(obj);
    oos.close();
    return baos.toByteArray();
}

private static <T extends Serializable> T unpickle(byte[] b, Class<T> cl)
       throws IOException, ClassNotFoundException 
{
    ByteArrayInputStream bais = new ByteArrayInputStream(b);
    ObjectInputStream ois = new ObjectInputStream(bais);
    Object o = ois.readObject();
    return cl.cast(o);
}
Run Code Online (Sandbox Code Playgroud)