我理解不兼容的serialVersionUID背后的理论(即你可以区分同一类的不同编译版本),但我看到一个我不理解的问题,并没有陷入明显的错误原因(不同的编译版本同一类)。
我正在测试序列化/反序列化过程。所有代码都在同一个VM中的一台计算机上运行,并且序列化和反序列化方法都使用相同版本的编译类。序列化工作正常。被序列化的类非常复杂,包含许多其他类(java类型和UDT),并包含引用循环。我没有在任何课程中声明自己的UID。
这是代码:
public class Test {
public static void main(String[] args) throws Exception {
ContextNode context = WorkflowBuilder.getSimpleSequentialContextNode();
String contextString = BinarySerialization.serializeToString(context);
ContextNode contextD = BinarySerialization.deserializeFromString(ContextNode.class, contextString);
}
}
public class BinarySerialization {
public static synchronized String serializeToString(Object obj) throws Exception {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(byteStream);
oos.writeObject(obj);
oos.close();
return byteStream.toString();
}
public static synchronized <T> T deserializeFromString(Class<T> type, String byteString) throws Exception {
T object = null;
ByteArrayInputStream byteStream = new ByteArrayInputStream(byteString.getBytes());
ObjectInputStream in = new ObjectInputStream(byteStream);
object = (T)in.readObject();
in.close();
return object;
}
}
我在反序列化时收到InvalidClassException(本地类不兼容:stream classdesc serialVersionUID = -7189235121689378989,local class serialVersionUID = -7189235121689362093)。
底层问题是什么?我该如何解决?
由于
修改
我应该说明这个的目的。序列化数据都需要存储在sqlite数据库中,并通过线路发送到其他客户端。如果String
是传递序列化数据的错误格式,那么我应该使用什么来存储和传递数据呢?再次感谢。
答案 0 :(得分:12)
第一条规则:处理二进制数据时,请勿使用String
或char[]
或Reader
或Writer
。
您正在处理二进制数据并尝试将其放入String
。不要这样做,这是一个固有的破坏性操作。
下一步:byteStream.toString()
的返回值绝不代表ByteArrayOutputStream
的实际内容。您需要使用.getBytes()
并传递byte[]
(请记住:将二进制数据视为二进制数据,而不是String
)。