serializable_为什么要在Java的Serializable类中使用SerialVersionUID

serializable

serializable

序列化和SerialVersionUID始终是许多Java开发人员的难题。 我经常会看到类似此SerialVersionUID的问题,或者如果不在Serializable类中声明SerialVersionUID会发生什么情况? 除了涉及的复杂性和罕见的使用之外,这些问题的另一个原因是Eclipse IDE发出警告,警告不要缺少SerialVersionUID,例如“ Serializable类Customer不会声明long类型的静态最终SerialVersionUID字段” 。 在本文中,您不仅将学习Java SerialVersionUID的基础知识,而且还将了解其在序列化和反序列化过程中的作用。 通过实现标记接口java.io.Serializable将一个类声明为Serializable时,如果您尚未使用Externalizable接口自定义过程,则Java运行时将使用默认的Serialization机制将该类的实例持久化到磁盘中。 在序列化过程中,Java运行时会为一个类创建一个版本号,以便以后可以反序列化它。 此版本号在Java中称为SerialVersionUID 。 如果在反序列化过程中,SerialVersionUID不匹配,则进程将失败,并在线程“ main” java.io.InvalidClassException中以InvalidClassException作为Exception ,同时还会打印类名和相应的SerialVersionUID。 解决此问题的快速解决方案是复制SerialVersionUID并将其声明为类中的私有静态最终长常量。 在本文中,我们将了解为什么要在Java中使用SerialVersionUID以及如何使用serialver JDK工具生成此ID。 如果您不熟悉序列化,则还可以查看“十大Java序列化面试”问题,以评估您的知识并找到理解上的空白以供进一步阅读。 与并发和多线程类似,序列化是另一个主题,值得一读。

就像我说的那样,当我们不声明SerialVersionUID作为类中的静态,最终值和长整型值时,序列化机制会为我们创建它。 这种机制对许多细节敏感,包括您的类中的字段,访问修饰符,它们实现的接口,甚至不同的Compiler实现,对类的任何更改或使用不同的编译器都可能导致产生不同的SerialVersionUID ,许多最终都会停止重新加载序列化的数据。 依靠Java序列化机制生成此id太冒险了,这就是为什么建议在Serializable类中声明显式SerialVersionUID的原因。 我强烈建议阅读Joshua Bloch的经典Java著作“ Effective Java”,以了解Java序列化和不正确处理它的问题。 顺便说一下,JDK还提供了一个名为serialver的工具,位于我的机器C:\ Program Files \ Java \ jdk1.6.0_26 \ bin \ serialver.exe的JAVA_HOME文件夹的bin目录中,该工具可用于为旧版本生成SerialVersionUID类。 如果您在类中进行了更改(这会破坏序列化并且您的应用程序无法重新加载序列化的实例),这将非常有用。 您可以简单地使用此工具为旧实例创建SerialVersionUID,然后通过声明一个privatestaticfinallong SerialVersionUID字段在您的类中显式使用它。 顺便说一句,出于性能和安全性的考虑,强烈建议您使用自定义二进制格式进行序列化,Effective Java再次提供了几项,详细说明了自定义格式的优点。

您可以使用JDK的serialver工具为类生成SerialVersionUID。 这对于正在发展的类特别有用,它以易于复制的格式返回SerialVersionUID。 您可以使用serialver JDK工具,如以下示例所示:

$ serialver
use: serialver [-classpath classpath] [-show] [classname...]

$ serialver -classpath . Hello
Class Hello is not Serializable.

$ serialver -classpath . Hello
Hello:    static final long SerialVersionUID = -4862926644813433707L;

您甚至可以通过运行命令$ serialver -show以GUI形式使用serialver工具,这将打开串行版本检查器,该检查器将使用完整的类名并显示其串行版本。

现在我们知道什么是SerialVersionUID以及为什么在Serializable类中声明它很重要,是时候修改一些与Java SerialVersionUID相关的重要事实了。

  1. SerialVersionUID用于对序列化数据进行版本控制。 如果类的SerialVersionUID与序列化的实例匹配,则只能反序列化该类。
  2. 当我们不在类中声明SerialVersionUID时,Java运行时会为我们生成它,但是该过程对许多类元数据敏感,包括字段数,字段类型,字段访问修饰符,由类实现的接口等。您可以在Oracle的序列化文档中可以找到准确的信息。
  3. 建议将SerialVersionUID声明为私有静态最终长型变量,以避免使用默认机制。 如果您错过了某些Eclipse之类的IDE,也会显示警告,例如“ Serializable类Customer不会声明long类型的静态最终SerialVersionUID字段” 。 尽管可以通过转到窗口>首选项> Java>编译器>错误/警告>潜在的编程问题来禁用此警告,但我建议不要这样做。 唯一的情况是,在不需要恢复数据时,我会很粗心。 这是在Eclipse IDE中出现此错误的样子,您需要做的就是接受第一个快速修复。
  4. Java中的SerialVersionUID是什么以及为什么需要它

  5. 您甚至可以使用JDK中的serialver工具为Java中的类生成Serial Version。 它还具有一个GUI,可以通过传递-show参数来启用它。
  6. 明确声明SerialVersionUID是Java中的序列化最佳实践,以避免在反序列化期间出现任何问题,尤其是在运行依赖于序列化数据的客户端服务器应用程序(例如RMI)的情况下。

这就是Java中的SerialVersionUID的全部内容。 现在我们知道了为什么在类中声明SerialVersionUID很重要。 您可以感谢您的IDE的提醒,这可能会破坏您的类的反序列化。

如果您想了解有关序列化和相关概念的更多信息,还可以看到以下精彩文章:

翻译自: https://www.javacodegeeks.com/2014/05/why-use-serialversionuid-inside-serializable-class-in-java.html

serializable

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值