Java 这是什么意思:可序列化类未声明静态最终 serialVersionUID 字段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2288937/
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
What does it mean: The serializable class does not declare a static final serialVersionUID field?
提问by Roman
I have the warning message given in the title. I would like to understand and remove it. I found already some answers on this question but I do not understand these answers because of an overload with technical terms. Is it possible to explain this issue with simple words?
我有标题中给出的警告信息。我想了解并删除它。我已经在这个问题上找到了一些答案,但由于技术术语过多,我不明白这些答案。是否可以用简单的语言来解释这个问题?
P.S. I know what OOP is. I know what is object, class, method, field and instantiation.
PS我知道什么是OOP。我知道什么是对象、类、方法、字段和实例化。
P.P.S. If somebody needs my code it is here:
PPS 如果有人需要我的代码,它在这里:
import java.awt.*;
import javax.swing.*;
public class HelloWorldSwing extends JFrame {
JTextArea m_resultArea = new JTextArea(6, 30);
//====================================================== constructor
public HelloWorldSwing() {
//... Set initial text, scrolling, and border.
m_resultArea.setText("Enter more text to see scrollbars");
JScrollPane scrollingArea = new JScrollPane(m_resultArea);
scrollingArea.setBorder(BorderFactory.createEmptyBorder(10,5,10,5));
// Get the content pane, set layout, add to center
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
content.add(scrollingArea, BorderLayout.CENTER);
this.pack();
}
public static void createAndViewJFrame() {
JFrame win = new HelloWorldSwing();
win.setTitle("TextAreaDemo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
}
//============================================================= main
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndViewJFrame();
}
});
}
}
采纳答案by Bozho
From the javadoc:
从javadoc:
The serialization runtime associates with each serializable class a version number, called a
serialVersionUID
, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a differentserialVersionUID
than that of the corresponding sender's class, then deserialization will result in anInvalidClassException
. A serializable class can declare its ownserialVersionUID
explicitly by declaring a field named"serialVersionUID"
that must be static, final, and of type long:
序列化运行时将每个可序列化类与一个称为 a 的版本号相关联,
serialVersionUID
在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否已为该对象加载了与序列化兼容的类。如果接收者为对象加载了一个serialVersionUID
与相应发送者的类不同的类,那么反序列化将导致InvalidClassException
. 一个可序列化的类可以serialVersionUID
通过声明一个"serialVersionUID"
必须是 static、final 和 long 类型的字段来显式声明它自己:
You can configure your IDE to:
您可以将 IDE 配置为:
- ignore this, instead of giving a warning.
- autogenerate an id
- 忽略这一点,而不是发出警告。
- 自动生成一个 id
As per your additional question "Can it be that the discussed warning message is a reason why my GUI application freeze?":
根据您的附加问题“讨论的警告消息是否是我的 GUI 应用程序冻结的原因?”:
No, it can't be. It can cause a problem only if you are serializing objects and deserializing them in a different place (or time) where (when) the class has changed, and it will not result in freezing, but in InvalidClassException
.
不,不可能。仅当您序列化对象并在不同的位置(或时间)(其中(何时)类发生更改时)对对象进行序列化和反序列化时,它才会导致问题,并且不会导致冻结,而是在InvalidClassException
.
回答by Thomas L?tzer
Any class that can be serialized (i.e. implements Serializable
) should declare that UID and it must be changed whenever anything changes that affects the serialization (additional fields, removed fields, change of field order, ...). The field's value is checked during deserialization and if the value of the serialized object does not equal the value of the class in the current VM, an exception is thrown.
任何可以序列化(即实现Serializable
)的类都应该声明该 UID,并且每当影响序列化的任何更改(附加字段、删除的字段、字段顺序的更改等)时,都必须更改该 UID。在反序列化期间检查该字段的值,如果序列化对象的值不等于当前 VM 中类的值,则会引发异常。
Note that this value is special in that it is serialized with the object even though it is static, for the reasons described above.
请注意,此值的特殊之处在于它与对象一起序列化,即使它是静态的,原因如上所述。
回答by Robin
The reasons for warning are documented here, and the simple fixes are to turn off the warning or put the following declaration in your code to supply the version UID. The actual value is not relevant, start with 999 if you like, but changing it when you make incompatible changes to the class is.
此处记录了警告的原因,简单的修复方法是关闭警告或将以下声明放入您的代码中以提供版本 UID。实际值不相关,如果您愿意,可以从 999 开始,但是当您对类进行不兼容的更改时更改它。
public class HelloWorldSwing extends JFrame {
JTextArea m_resultArea = new JTextArea(6, 30);
private static final long serialVersionUID = 1L;
回答by user207421
it must be changed whenever anything changes that affects the serialization (additional fields, removed fields, change of field order, ...)
每当影响序列化的任何更改(附加字段、删除的字段、字段顺序的更改等)时,都必须更改它
That's not correct, and you will be unable to cite an authoriitative source for that claim. It should be changed whenever you make a change that is incompatible under the rules given in the Versioning of Serializable Objectssection of the Object Serialization Specification, which specifically does notinclude additional fields or change of field order, andwhen you haven't provided readObject(), writeObject(),
and/or readResolve()
or /writeReplace()
methods and/or a serializableFields
declaration that could cope with the change.
这是不正确的,您将无法引用该声明的权威来源。每当你做出改变不兼容下在给定的规则应当改变可序列化的对象版本的的部分对象序列化规范,其特异性地并不包括额外的字段或字段顺序的变化,并且当没有提供readObject(), writeObject(),
和/或readResolve()
或/writeReplace()
方法和/或serializableFields
可以应对变化的声明。
回答by MrMas
The other answers so far have a lot of technical information. I will try to answer, as requested, in simple terms.
到目前为止,其他答案有很多技术信息。我会尽量按要求简单地回答。
Serialization is what you do to an instance of an object if you want to dump it to a raw buffer, save it to disk, transport it in a binary stream (e.g., sending an object over a network socket), or otherwise create a serialized binary representation of an object. (For more info on serialization see Java Serialization on Wikipedia).
如果要将对象转储到原始缓冲区、将其保存到磁盘、以二进制流传输(例如,通过网络套接字发送对象)或以其他方式创建序列化对象,那么序列化就是对对象实例所做的操作。对象的二进制表示。(有关序列化的更多信息,请参阅维基百科上的Java 序列化)。
If you have no intention of serializing your class, you can add the annotation just above your class @SuppressWarnings("serial")
.
如果您不打算序列化您的类,您可以在您的类上方添加注释@SuppressWarnings("serial")
。
If you are going to serialize, then you have a host of things to worry about all centered around the proper use of UUID. Basically, the UUID is a way to "version" an object you would serialize so that whatever process is de-serializing knows that it's de-serializing properly. I would look at Ensure proper version control for serialized objectsfor more information.
如果您要序列化,那么您有很多事情要担心,所有这些都围绕着正确使用 UUID。基本上,UUID 是一种“版本化”要序列化的对象的方法,以便任何正在反序列化的进程都知道它正在正确地反序列化。我会查看确保序列化对象的正确版本控制以获取更多信息。