使用serialVersionUID或抑制警告?

我想创build一个类,例如,扩展HttpServlet? 我的编译器警告我,我的类应该有一个serialVersionUID。 如果我知道这个对象永远不会被序列化,我应该定义它还是添加一个注释来抑制这些警告?

你会怎么做,为什么?

我不知道Java的最佳实践,但是对我来说,如果你声称序列化永远不会发生,你可以添加一个抛出的writeObject方法。 然后压制警告,在知道它不可能适用于你的情况下是安全的。

否则有人可能会在未来通过父类序列化您的对象,并最终以默认序列化的forms,其中:

  • 该表单在您的代码的不同版本之间不兼容。
  • 你已经打消了这种情况的警告。

添加一个ID听起来像一个闪光,因为你真正想要做的不是序列化。 期望呼叫者不要序列化你的对象意味着你期望他们“知道”他们的HttpServlet是你的课程。 这个多态性的违背是你的头上有一个序列化的对象,不能被序列化,至less你可以做的是确保不知情的来电者知道它。

如果您不打算序列化实例,请添加SuppressWarning。

生成的序列号可能有点危险。 它build议你有意给它一个序列号,并保存序列化和反序列化。 很容易忘记更新您的应用程序的更新版本中的序列号,您的类更改。 如果类字段已更改,则反序列化将失败。 有一个SuppressWarning至less告诉读者你的代码,你不打算序列化这个类。

我拒绝被Eclipse的恐吓join到我的代码混乱!

我只是将Eclipseconfiguration为不会在缺lessserialVersionUID时生成警告。

即使你知道这个对象将被序列化,也不需要生成serialVersionUID,因为java会自动生成serialVersionUID,并且会自动跟踪更改,所以你的序列化将始终正常工作。 只有当你知道自己在做什么时才能生成它(向后序列化兼容性,手动更改跟踪等)

所以我想说的是,在大多数情况下,抑制警告是最好和最安全的解决scheme。

感谢@史蒂夫·杰索普对此的回答。 这是5行代码…几乎没有麻烦。

我在课堂上面添加了@SuppressWarnings("serial")

我也加了这个方法:

 private void writeObject(ObjectOutputStream oos) throws IOException { throw new IOException("This class is NOT serializable."); } 

希望这是史蒂夫的意思:)

让Eclipse生成一个ID。 快捷方便。 警告不容忽视。 如果你已经到达对象/已经/将要被序列化的地步,也可以节省很多麻烦。

这个警告使我疯狂,因为每次你将一个Swing类子类化时,你都知道你永远不会序列化它,但是有那个愚蠢的警告。 但是,我让Eclipse生成一个。

每个实现可序列化的类生成SVUID是很好的。 原因很简单。 你永远不知道什么时候会被你或者某个第三方序列化。 可以configuration很多将序列化servlet的服务。 对于每个IDE存在插件,它会生成一个或只是使用模板并设置svuid = 1L。

如果省略serialVersionUID,java将在编译时为类生成一个(它随每个编译而改变)。

反序列化对象时,将反序列化对象的serialVersionUID与jvm中的类进行比较。 如果它们不同,则认为它们不兼容,抛出exception。 这可能发生在升级程序和反序列化旧类之后。

我总是使用1L的serialversionUID。 它不会伤害(与生成的默认值相比),并且在稍后通过增加id来留下兼容性的选项。

请按照此链接获得详细的解释: http : //technologiquepanorama.wordpress.com/2009/02/13/what-is-use-of-serialversiouid/

这取决于。

如果您使用不同的编译器多次编译您的源代码,您编译的代码可能会有不同的serializationId,这将打破序列化。 然后,您需要在代码中明确地使用常量serializationId。 它必须是静态的,最终的和每个类(不可inheritance的)。

但是,如果您始终使用特定的编译器编译您的代码,并始终将您的代码一次性部署到所有虚拟机中,则可能需要严格的版本检查,并且希望确保只要有一个版本的代码正在运行这种情况下,你应该压制警告。 因此,如果虚拟机未成功部署并运行旧版本的代码,则可能期望在序列化期间发生exception,而不是反序列化的exception对象。 这恰好是我的情况,我们以前有一个非常大的集群,我们需要严格的版本检查来找出任何部署问题。

无论如何,可能你应该尽可能地避免序列化,因为与协议缓冲区或节俭相比,默认序列化非常慢,并且不支持跨语言互操作性。

如果您知道您的应用程序永远不会序列化,请禁用整个应用程序的警告。 这可以使用javac命令行参数完成:

javac -Xlint -Xlint:-serial *******

这样你将有除“串行”之外的所有警告。 IDE-s和像Maven / SBT / Gradle这样的构build工具可以正常工作。