244

我有标题中给出的警告信息。我想了解并删除它。我已经找到了关于这个问题的一些答案,但由于技术术语过多,我不理解这些答案。能不能用简单的话来解释这个问题?

PS我知道OOP是什么。我知道什么是对象、类、方法、字段和实例化。

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

}
4

5 回答 5

168

javadoc

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

您可以将 IDE 配置为:

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

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

不,不可能。仅当您在类已更改的不同位置(或时间)对对象进行序列化和反序列化时,它才会导致问题,并且不会导致冻结,而是在InvalidClassException.

于 2010-02-18T13:41:39.893 回答
45

到目前为止,其他答案有很多技术信息。根据要求,我将尝试以简单的方式回答。

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

如果您不打算序列化您的课程,您可以在您的课程上方添加注释@SuppressWarnings("serial")

如果你要序列化,那么你有很多事情要担心,所有这些都围绕着正确使用 UUID。基本上,UUID 是一种对您将序列化的对象进行“版本化”的方法,以便任何正在反序列化的进程都知道它正在正确地反序列化。我会查看确保序列化对象的正确版本控制以获取更多信息。

于 2013-04-26T16:36:27.633 回答
37

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

public class HelloWorldSwing extends JFrame {

        JTextArea m_resultArea = new JTextArea(6, 30);
        private static final long serialVersionUID = 1L;
于 2010-02-18T14:19:22.313 回答
27

每当影响序列化的任何更改(附加字段、删除字段、字段顺序更改……)时,都必须更改它

这是不正确的,您将无法引用该声明的权威来源。每当您根据Object Serialization Specification的“可序列化对象的版本控制”部分中给出的规则进行不兼容的更改时,都应该更改它,该规则特别不包括附加字段或字段顺序的更改,并且当您没有提供和/或方法和/或可以应对变化的声明。readObject(), writeObject(),readResolve()/writeReplace()serializableFields

于 2010-02-18T21:16:01.013 回答
5

任何可以序列化的类(即 implements Serializable)都应该声明 UID,并且只要有任何影响序列化的变化(附加字段、删除字段、字段顺序更改……),就必须更改它。在反序列化过程中会检查该字段的值,如果序列化对象的值不等于当前 VM 中类的值,则会引发异常。

请注意,由于上述原因,该值的特殊之处在于它与对象一起序列化,即使它是静态的。

于 2010-02-18T13:42:40.713 回答