Java 是否使用SerialVersionId或抑制警告?

Java 是否使用SerialVersionId或抑制警告?,java,serialization,serialversionuid,Java,Serialization,Serialversionuid,我想创建一个类,例如扩展HttpServlet?我的编译器警告我,我的类应该有一个serialVersionUID。如果我知道这个对象永远不会被序列化,我应该定义它还是添加注释来抑制这些警告 你会做什么?为什么?让Eclipse快速、简单地生成一个ID。警告不容忽视。如果您遇到对象/必须/被序列化的情况,也可以为您节省很多麻烦。如果您不打算序列化实例,请添加一个SuppressWarning 生成的串行ID可能有点危险。它表明您有意为它提供了一个序列号,并且它被保存以进行序列化和反序列化。在类发

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


你会做什么?为什么?

让Eclipse快速、简单地生成一个ID。警告不容忽视。如果您遇到对象/必须/被序列化的情况,也可以为您节省很多麻烦。

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


生成的串行ID可能有点危险。它表明您有意为它提供了一个序列号,并且它被保存以进行序列化和反序列化。在类发生更改的应用程序的较新版本中,很容易忘记更新序列号。如果类字段已更改,反序列化将失败。有一个SuppressWarning至少会告诉代码的读者您不打算序列化这个类。

我不知道Java的最佳实践,但我突然想到,如果您声称序列化永远不会发生,您可以添加一个writeObject方法来抛出。然后抑制警告,因为它不可能适用于您

否则,将来可能会有人通过父类序列化您的对象,并以默认的序列化形式结束,其中:

  • 表单在不同版本的代码之间不兼容
  • 您已取消显示这种情况的警告

添加一个ID听起来像是一个预兆,因为您真正想要做的不是序列化。期望调用方不序列化对象意味着您希望调用方“知道”它们的HttpServlet何时属于您的类。这种违反多态性的行为是因为你有一个不能序列化的可序列化对象,你至少可以确保粗心的调用方知道它。

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

我拒绝被Eclipse吓坏,给我的代码添加混乱


我只是将Eclipse配置为不生成关于缺少serialVersionUID的警告。

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


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

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

当反序列化对象时,反序列化对象的SerialVersionId将与jvm中类的SerialVersionId进行比较。如果它们不同,则认为它们不兼容,并引发异常。例如,在升级程序和反序列化旧类之后,可能会发生这种情况


我总是使用1L表示serialversionUID。它不会造成伤害(与生成的默认值相比),并且它仍然保留了通过增加id来破坏兼容性的选项。

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

请点击此链接获取详细解释:

感谢@Steve Jessop对此的回答。这是5行代码。。。没什么麻烦

我将
@SuppressWarnings(“serial”)
添加到了相关类的正上方

我还添加了以下方法:

private void writeObject(ObjectOutputStream oos) throws IOException {
   throw new IOException("This class is NOT serializable.");
}
希望这就是史蒂夫的意思:)

视情况而定

如果使用不同的编译器多次编译源代码,则编译后的代码可能具有不同的SerializationID,这将破坏序列化。然后,您需要在代码中显式地使用常量serializationId。它必须是静态的、最终的,并且是每个类(不可继承的)

但是,如果您总是使用特定的编译器编译代码,并且总是一次性将代码部署到所有虚拟机上,那么您可能需要严格的版本检查,并希望确保任何时候只有一个版本的代码在运行,在这种情况下,您应该抑制警告。所以,如果VM未成功部署并且正在运行旧版本的代码,您可能会在序列化过程中遇到异常,而不是怪癖反序列化对象。这恰好是我的情况,我们曾经有一个非常非常大的集群,我们需要严格的版本检查来发现任何部署问题


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

如果您知道您的应用程序从不序列化内容,请在应用程序范围内取消此警告。这可以使用javac命令行参数完成:

javac-Xlint-Xlint:-串行******


这样,您将获得除“串行”之外的所有警告。IDE-s和Maven/SBT/Gradle等构建工具可以很好地配合使用。

我不同意。本例中的ID是无用的。在我看来,这个警告应该被禁止。警告是一种提示,要求你做出明智的决定,而不是盲目遵循的指示。@McDowell序列化JavaDoc说强烈建议这样做。我的意思是,当然,你可以说太阳报/甲骨文公司的人都是疯子,你有更好的身份证