Java 使用 serialVersionUID 还是禁止警告?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/146715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:54:30  来源:igfitidea点击:

Use the serialVersionUID or suppress warnings?

javaserializationserialversionuid

提问by Okami

I want to create a class that, for example, extends HttpServlet? My compiler warns me that my class should have a serialVersionUID. If I know that this object will never be serialized, should I define it or add an annotation to suppress those warnings?

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

What would you do and why?

你会怎么做,为什么?

回答by xmjx

Let Eclipse generate an ID. Quick and easy. Warnings are not to be ignored. Also saves you lots of trouble should you ever come to the point where the object /has/ to be serialized.

让 Eclipse 生成一个 ID。快捷方便。警告不可忽视。如果您到达对象 /has/ 被序列化的地步,还可以为您省去很多麻烦。

回答by Benno Richters

If you do not plan to serialize instances, add a SuppressWarning.

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

A generated serial ID can be a bit dangerous. It suggests that you intentionally gave it a serial number and that it is save to serialize and deserialize. It's easy to forget to update the serial number in a newer version of your application where your class is changed. Deserialization will fail if the class fields have been changed. Having a SuppressWarning at least tells the reader of your code that you did not intend to serialize this class.

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

回答by Steve Jessop

I don't know Java best practices, but it occurs to me that if you are claiming that serialization will never happen, you could add a writeObject method which throws. Then suppress the warning, safe in the knowledge that it cannot possibly apply to you.

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

Otherwise someone might in future serialize your object through the parent class, and end up with a default serialized form where:

否则,将来有人可能会通过父类序列化您的对象,并最终得到一个默认的序列化形式,其中:

  • the form isn't compatible between different versions of your code.
  • you've suppressed the warning that this is the case.
  • 该表单在不同版本的代码之间不兼容。
  • 你已经抑制了这种情况的警告。

Adding an ID sounds like a bodge, since what you really want to do is not serialize. Expecting callers not to serialize your object means that you expect them to "know" when their HttpServlet is of your class. That breach of polymorphism is on your head for having a Serializable object which must not be serialized, and the least you can do is make sure unwary callers know about it.

添加 ID 听起来很麻烦,因为您真正想做的不是序列化。期望调用者不序列化您的对象意味着您期望他们“知道”他们的 HttpServlet 何时属于您的类。由于拥有一个不能被序列化的 Serializable 对象,多态性的破坏是你的头脑,你至少可以确保粗心的调用者知道它。

回答by Paul Tomblin

That warning drives me crazy, because every time you subclass a Swing class, you knowyou're never going to serialize it, but there is that stupid warning. But yeah, I let Eclipse generate one.

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

回答by ykaganovich

I refuse to be terrorized by Eclipse into adding clutter to my code!

我拒绝被 Eclipse 恐吓,让我的代码变得混乱!

I just configure Eclipse to not generate warnings on missing serialVersionUID.

我只是将 Eclipse 配置为在缺少 serialVersionUID 时不生成警告。

回答by serg

Even if you know this object will be serialized there is no need to generate serialVersionUID because java will automatically generate it for you and will automatically keep track of changes so your serialization will always work just fine. You should generate it only if you know what you are doing (backward serialization compatibility, manual change tracking etc.)

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

So I would say suppressing the warning is the best and safest solution in most cases.

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

回答by Glever

If you leave out a serialVersionUID java will generate one for the class at compile time (it changes with every compilation).

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

When deserializing objects the serialVersionUID of the deserialized object is compared to that of the class in the jvm. If they are different they are considered incompatible and an Exception is thrown. This can happen for instance after upgrading your program and deserializing old classes.

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

I always use 1L for serialversionUID. It doesn't hurt (compared to the default generated) and it still leaves the option of breaking compatibility later by incrementing the id.

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

回答by Rastislav Komara

It is good to generate SVUID to everyclass implementing serializable. The reason is simple. You neverknow when it will be serialized by you or by some 3rd party. There can be configured a lot of services which will serialize servlets. For every IDE exists plugin which generates one or just use template and set svuid = 1L.

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

回答by Mike

Thanks @ Steve Jessop for his answer on this. It was 5 lines of code... hardly a hassle.

感谢 @ Steve Jessop 对此的回答。这是 5 行代码......几乎没有麻烦。

I added @SuppressWarnings("serial")just above the class in question.

@SuppressWarnings("serial")在有问题的班级上方添加了。

I also added this method:

我还添加了这个方法:

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

Hopefully that's what Steve meant :)

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