Java序列化 - 不兼容的serialVersionUID

4
我理解不兼容的serialVersionUIDs背后的理论(即您可以区分同一类的不同编译版本),但我遇到了一个问题,我不明白并且不属于明显的错误原因(相同类的不同编译版本)。
我正在测试序列化/反序列化过程。所有代码都在同一台机器上运行,在同一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(本地类不兼容:流类描述符serialVersionUID = -7189235121689378989,本地类serialVersionUID = -7189235121689362093)。

这是什么根本问题?我应该如何解决它?

谢谢

编辑 我应该说明一下目的。序列化数据既需要存储在sqlite数据库中,也需要通过网络传输给其他客户端。如果String是传递序列化数据的错误格式,那么我应该使用什么来存储和传递数据?再次感谢。


2
byte[]是二进制数据的正确容器。任何严肃的存储格式或传输协议都应该能够直接处理二进制数据。 - Joachim Sauer
我正在使用Jabber/XMPP进行通信,这是一种基于文本的协议 - 我可以将byte[]编码为base64吗? - MalcomTucker
没错,BASE64是通过XML传输二进制数据的常见方式。 - Joachim Sauer
@MalcomTucker 我对你报告的异常有所怀疑:如果我重做你的示例,我会在“ObjectInputStream in = new ObjectInputStream(byteStream);”这一行抛出“Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: EFBFBDEF”的异常。 - wh81752
1个回答

12

第一条规则:处理二进制数据时,永远不要使用 Stringchar[]ReaderWriter

如果你正在处理二进制数据并试图将其放入一个 String 中,请不要这样做,因为这是一个本质上有问题的操作。

接下来,byteStream.toString() 的返回值不以任何方式表示 ByteArrayOutputStream 的实际内容。你需要使用 .getBytes() 并传递 byte[](记住:将二进制数据视为二进制数据,而不是 String)。


不要这样做,那是一个本质上有问题的操作。这样做可能会导致程序崩溃或产生意外结果。建议使用更可靠和安全的方法来完成相同的任务。 - Keefer Rourke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接