【问题标题】:Java Serialization 1.4 vs 1.6Java 序列化 1.4 与 1.6
【发布时间】:2008-11-25 20:21:08
【问题描述】:

我有一个 java 程序必须编译为 1.4,另一个程序可以是任何程序(所以,1.4 或 1.6),这两个程序需要来回传递序列化对象。如果我在两个程序都可以看到的地方定义一个可序列化的类,java的序列化是否仍然有效,还是我只需要1.6-1.6或1.4-1.4?

【问题讨论】:

  • 在跨语言/跨平台/跨类可能会随着时间而改变时,我是唯一一个从不相信序列化机制的人吗?如果性能不重要,我倾向于序列化为 XML 并返回...
  • @Uni,通常我只会在两个进程都从完全相同的 jar 中获取序列化类时才在进程之间使用序列化,例如当两个进程都在同一台机器上时。如果进程在不同的机器上,我会选择 XML 的东西。

标签: java serialization


【解决方案1】:

确保要序列化的类定义并赋值给static final long serialVersionUID,你应该没问题。

也就是说,通常我不会这样做。我的偏好是仅在单个进程内或两个进程之间在同一台机器上使用普通序列化,并从同一个 jar 文件中获取序列化类。如果不是这样,序列化为 XML 是更好、更安全的选择。

【讨论】:

    【解决方案2】:

    serialVersionUID 一起,包结构必须保持一致以进行序列化,因此如果您在1.4 中有myjar.mypackage.myclass,则在1.6 中必须有myjar.mypackage.myclass

    在包结构中的某个位置包含 Java 版本或您的发布版本并不罕见。即使 serialVersionUID 在编译之间保持不变,包结构也会导致在运行时抛出不兼容的版本异常。

    顺便说一句,如果您在类中实现Serializable,如果缺少serialVersionUID,您应该会收到编译器警告。

    在我看来(以及基于多年相当痛苦的经验)Java 原生序列化充满了问题,应该尽可能避免,尤其是在有出色的 XML/JSON 支持的情况下。如果您确实必须本机序列化,那么我建议您将类隐藏在接口后面并在后台实现工厂模式,该模式将在需要时创建正确类的对象。

    您还可以使用此抽象来检测不兼容的版本异常,并在后台执行任何必要的转换以迁移对象中的数据。

    【讨论】:

      【解决方案3】:

      除非另有说明,否则 Java 库类应该在 1.4 和 1.6 之间具有兼容的序列化形式。 Swing 明确声明它在版本之间不兼容,因此如果您尝试序列化 Swing 对象,那么您就不走运了。

      您可能会遇到 javac 生成的代码略有不同的问题。这将更改serialVersionUID。您应该确保在所有可序列化的类中明确声明 UID。

      【讨论】:

      • 如果你没有显式声明serialVersionUID,你可以从两个不同的编译中得到关于不同版本的异常,使用完全相同的代码,使用完全相同的编译器和完全相同的环境。
      • @Paul:我认为默认的 serialVersionUID 被很好地指定为类成员的函数。我从未见过它虚假地改变。你能描述一下发生这种情况的场景吗?
      • 是的,这将是一个奇怪的编译器,而不是为用于计算 serialVersionUID 的数据添加随机性(尽管我相信在技术上符合规范)。
      • 我也不认为会有所不同,但请阅读第 4.6 节中的注释java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/…
      • “计算对类细节高度敏感,这些细节可能因编译器实现而异” - 但如果这些细节保持不变,那么它会是一个奇怪(但不一定不兼容)的编译器,它会改变 UID。
      【解决方案4】:

      不,不同版本的 JVM 不会破坏序列化本身。

      如果您正在序列化的某些对象来自 Java 运行时,并且它们的类发展不兼容,您将看到失败。大多数核心 Java 类对此都很谨慎,但过去在某些包中存在不连续性。

      多年来,我已经成功地将序列化(在 RMI 的上下文中)与来自运行不同版本 Java 运行时的不同机器上的不同编译的类一起使用。

      我不想离原始问题太远,但我想指出,无论格式如何,演变一个序列化类总是需要小心。这不是 Java 序列化特有的问题。无论您使用 XML、JSON、ASN.1 等进行序列化,您都必须处理相同的概念。Java 序列化对允许的内容以及如何进行允许的更改给出了相当清晰的规范。有时这是限制性的,有时有处方会有所帮助。

      【讨论】:

        【解决方案5】:

        如果双方使用相同的 jar 文件,它会在大多数情况下工作。但是,如果您使用相同包/模块/框架的不同版本(例如不同的 weblogic jar 或某些“罕见”异常的扩展使用),则需要进行大量集成测试才能获得批准。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-20
          • 2012-12-28
          • 1970-01-01
          • 2014-08-19
          • 1970-01-01
          • 1970-01-01
          • 2012-09-23
          • 2010-11-13
          相关资源
          最近更新 更多