这是什么意思:可序列化类没有声明静态最终的serialVersionUID字段?

发布于 2024-08-22 00:49:06 字数 1542 浏览 7 评论 0 原文

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

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

}

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.

P.P.S. If somebody needs my code it is here:

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

等往事风中吹 2024-08-29 00:49:06

来自 javadoc

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

您可以将 IDE 配置为:

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

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

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

From the 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 different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:

You can configure your IDE to:

  • ignore this, instead of giving a warning.
  • autogenerate an id

As per your additional question "Can it be that the discussed warning message is a reason why my GUI application freeze?":

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.

人疚 2024-08-29 00:49:06

到目前为止其他答案有很多技术信息。我会按照要求尝试用简单的语言来回答。

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

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

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

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).

If you have no intention of serializing your class, you can add the annotation just above your class @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 objects for more information.

束缚m 2024-08-29 00:49:06

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

public class HelloWorldSwing extends JFrame {

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

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.

public class HelloWorldSwing extends JFrame {

        JTextArea m_resultArea = new JTextArea(6, 30);
        private static final long serialVersionUID = 1L;
大姐,你呐 2024-08-29 00:49:06

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

这是不正确的,您将无法引用该声明的权威来源。每当您做出与 可序列化对象的版本控制部分“nofollow noreferrer">对象序列化规范,具体来说包含其他字段或更改字段顺序,并且当您未提供时readObject()、writeObject()、 和/或 readResolve()/writeReplace() 方法和/或 serializedFields可以应对变化的声明。

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 Objects section of the Object Serialization Specification, which specifically does not include additional fields or change of field order, and when you haven't provided readObject(), writeObject(), and/or readResolve() or /writeReplace() methods and/or a serializableFields declaration that could cope with the change.

寄人书 2024-08-29 00:49:06

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

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

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.

Note that this value is special in that it is serialized with the object even though it is static, for the reasons described above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文