Java 这意味着什么:serializable类不声明静态最终SerialVersionId字段?

Java 这意味着什么:serializable类不声明静态最终SerialVersionId字段?,java,serializable,serialversionuid,Java,Serializable,Serialversionuid,我在标题中给出了警告信息。我想理解并删除它。我在这个问题上已经找到了一些答案,但由于技术术语太多,我不理解这些答案。能用简单的话来解释这个问题吗 另外,我知道OOP是什么。我知道什么是对象、类、方法、字段和实例化 p.p.S.如果有人需要我的代码,请点击这里: import java.awt.*; import javax.swing.*; public class HelloWorldSwing extends JFrame { JTextArea m_resultAre

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

另外,我知道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();
                }
            });
        }

}
从:

序列化运行时将一个版本号(称为
serialVersionUID
)与每个可序列化类关联,该版本号在反序列化期间用于验证序列化对象的发送方和接收方是否为该对象加载了与序列化兼容的类。如果接收方为对象加载的类与相应发送方类的类具有不同的
serialVersionUID
,则反序列化将导致
InvalidClassException
。可序列化类可以通过声明名为
“serialVersionUID”
的字段来显式声明自己的
serialVersionUID
,该字段必须是静态的、最终的且类型为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()的情况下,如果您进行的更改与的部分中给出的规则不兼容,则应更改该字段,特别是不包括其他字段或字段顺序的更改
方法和/或可处理更改的
序列化字段
声明。

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

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

如果不打算序列化类,可以在类的上方添加注释
@SuppressWarnings(“serial”)


如果您要序列化,那么您需要担心的事情很多,都是围绕UUID的正确使用。基本上,UUID是一种对要序列化的对象进行“版本化”的方法,这样无论是反序列化的进程都知道它是正确反序列化的。我会查看更多信息

讨论的警告消息可能是我的GUI应用程序冻结的原因吗?不,与GUI冻结无关。Dup:I JFrame可序列化类?什么是UID以及如何声明它?我的代码是否“更改了影响序列化的内容”?序列化实际上意味着什么?是的,JFrame是一个实现可序列化的java.awt.Component。代码永远不会更改任何影响序列化的内容,只有程序员才会这样做。我不知道一个列表列出了所有影响序列化的更改。检查Java中序列化的描述。它未与对象序列化。除非您想要破坏兼容性,或者您已经通过偏离规范版本控制部分中的说明来破坏兼容性,否则不应更改它。这不包括添加或重新排序字段。正确的参考不是Wikipedia,而是对象序列化规范。“附加字段、删除字段、更改字段顺序”根本不重要。如果不实现readObject()来处理更改,则只有类型更改才有意义。您还可以让IDE自动生成一个类型更改。@BalusC-在eclipse中我们如何才能做到这一点?自动生成是否安全?@JediKnight在Eclispse中是窗口>首选项>Java>代码样式>清理>缺少的代码>激活“潜在编程问题”下的“添加串行版本ID”。然后,如果您处于默认配置文件中,显然必须将其另存为其他配置文件。在不使用序列化时,不要自动生成
serialVersionUID
。这已经在编译过程中发生了,而不必为了让IDE满意而用愚蠢的随机数毒害源代码。只需关闭Eclipse警告,因为这就是实际混乱的来源