它是什么意思:serializable类没有声明一个静态的final serialVersionUID字段?

时间:2010-02-18 13:40:10

标签: java serializable serialversionuid

我在标题中给出了警告信息。我想了解并删除它。我在这个问题上找到了一些答案,但由于技术术语过载,我不理解这些答案。是否可以用简单的词语来解释这个问题?

P.S。我知道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();
                }
            });
        }

}

5 个答案:

答案 0 :(得分:147)

来自javadoc

  

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

您可以将IDE配置为:

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

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

不,它不可能。只有在序列化对象并在不同的地方(或时间)反序列化它们时,它才会引起问题,其中(类)更改了类,并且它不会导致冻结,而是InvalidClassException

答案 1 :(得分:32)

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

public class HelloWorldSwing extends JFrame {

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

答案 2 :(得分:31)

到目前为止,其他答案都有很多技术信息。我会按照要求简单地回答。

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

如果您无意序列化课程,则可以在课程@SuppressWarnings("serial")上方添加注释。

如果你要序列化,那么你有很多事情要担心所有都围绕正确使用UUID。基本上,UUID是一种“版本化”您将序列化的对象的方法,这样无论什么进程反序列化都知道它正确地反序列化。我会查看Ensure proper version control for serialized objects以获取更多信息。

答案 3 :(得分:27)

  

任何事情都必须改变   影响序列化的更改   (其他字段,删除字段,   更改字段顺序,...)

这不正确,您将无法引用该声明的权威来源。每当您根据Versioning of Serializable ObjectsObject Serialization Specification部分中给出的规则进行不兼容的更改时,应该更改它,具体而言包含其他字段或更改字段如果您未提供readObject(), writeObject(),和/或readResolve()/writeReplace()方法和/或serializableFields声明,可以处理改变。

答案 4 :(得分:5)

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

请注意,这个值很特殊,因为它是对象序列化的,即使它是静态的,出于上述原因。