它的意思是:序列化类没有声明一个静态的最终serialVersionUID字段?

我有标题中给出的警告信息。我想理解并移除它。我已经找到了这个问题的一些答案,但我不明白这些答案,因为有太多的专业术语。有可能用简单的语言来解释这个问题吗?

附注:我知道OOP是什么。我知道什么是对象,类,方法,字段和实例化。

P.P.S.如果有人需要我的代码,它在这里:

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();
}
});
}


}
266215 次浏览

javadoc:

序列化运行时为每个可序列化类关联一个版本号,称为serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否为该对象加载了与序列化兼容的类。如果接收方为对象加载的类的serialVersionUID与相应发送方的类的serialVersionUID不同,则反序列化将导致InvalidClassException。可序列化类可以通过声明名为"serialVersionUID"的字段显式声明自己的serialVersionUID,该字段必须是静态的、final的且类型为long:

你可以配置你的IDE:

  • 忽略这一点,而不是给出警告。
  • 自动生成id

根据你的附加问题“讨论的警告消息是我的GUI应用程序冻结的原因吗?”:

不,不可能。只有当你序列化对象并在类改变的不同位置(或时间)反序列化它们时,才会导致问题,并且它不会导致冻结,而是在InvalidClassException中。

任何可以序列化的类(即实现Serializable)都应该声明UID,并且当任何影响序列化的变化(额外的字段,删除的字段,字段顺序的变化,…)时必须更改UID。在反序列化期间检查字段的值,如果序列化对象的值不等于当前VM中的类的值,则抛出异常。

注意,由于上面描述的原因,这个值是特殊的,因为即使它是静态的,它也被对象序列化了。

警告的原因记录在在这里中,简单的修复方法是关闭警告或在代码中加入以下声明来提供版本UID。实际值并不相关,如果您愿意,可以从999开始,但是在对类进行不兼容的更改时更改它是相关的。

public class HelloWorldSwing extends JFrame {


JTextArea m_resultArea = new JTextArea(6, 30);
private static final long serialVersionUID = 1L;

它必须在任何时候改变 影响序列化的更改 (额外的字段,删除的字段, 字段顺序的改变,…)

这是不正确的,你将无法引用一个权威来源的说法。当你在对象序列化规范可序列化对象的版本控制部分中给出的规则下做了不兼容的更改时,它应该被更改,特别是包含额外的字段或字段顺序的更改,当你没有提供readObject(), writeObject(),和/或readResolve()/writeReplace()方法和/或serializableFields声明可以应对更改时,而且

到目前为止,其他答案包含大量技术信息。我将尽量按要求用简单的语言回答。

序列化是你对一个对象的实例所做的事情,如果你想将它转储到原始缓冲区,保存到磁盘,以二进制流传输它(例如,通过网络套接字发送一个对象),或者以其他方式创建一个对象的序列化二进制表示。(有关序列化的更多信息,请参阅维基百科上的Java序列化)。

如果你不打算序列化你的类,你可以在你的类@SuppressWarnings("serial")上面添加注释。

如果您打算序列化,那么您就有很多事情要担心,这些事情都围绕着UUID的正确使用。基本上,UUID是一种对要序列化的对象进行“版本化”的方法,这样无论哪个进程正在反序列化,都知道它正在正确地反序列化。我将查看确保对序列化对象进行适当的版本控制以获得更多信息。