这是什么意思:可序列化的类不声明静态最终serialVersionUID字段?
标题中给出了警告信息。 我想了解并删除它。 我发现在这个问题上已经有了一些答案,但是由于技术术语超载,我不理解这些答案。 有没有可能用简单的词来解释这个问题?
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(); } }); } }
从javadoc :
序列化运行时与每个可序列化的类关联一个称为
serialVersionUID
的版本号,在反序列化过程中使用该版本号来validation序列化对象的发送者和接收者是否已经为该对象加载了关于序列化兼容的类。 如果接收者已经为与对应的发送者类具有不同serialVersionUID
的对象加载了类,则反序列化将导致InvalidClassException
。 一个可序列化的类可以通过声明一个名为"serialVersionUID"
的字段声明自己的serialVersionUID
,该字段必须是static,final和longtypes的:
您可以将您的IDEconfiguration为:
- 忽略这一点,而不是发出警告。
- 自动生成一个ID
根据您的附加问题“是否所讨论的警告信息是我的GUI应用程序冻结的原因?”:
不,不可以。 只有当序列化对象并在不同的地方(或时间)对类进行序列化并将其反序列化时,它才会导致问题,而类不会导致冻结,但会导致InvalidClassException
。
警告的原因在这里有logging,简单的修复是closures警告,或者在代码中提供以下声明来提供版本UID。 实际值是不相关的,如果你愿意,可以从999开始,但当你对课程进行不兼容的修改时,改变它。
public class HelloWorldSwing extends JFrame { JTextArea m_resultArea = new JTextArea(6, 30); private static final long serialVersionUID = 1L;
到目前为止的其他答案有很多技术信息。 我会尽量按照要求以简单的方式回答。
如果你想把它转储到一个原始的缓冲区,把它保存到磁盘,在二进制stream中传输它(例如通过networking套接字发送一个对象),或者创build一个序列化对象的二进制表示。 (有关序列化的更多信息,请参阅Wikipedia上的Java序列化 )。
如果你不打算序列化你的类,你可以在你的类@SuppressWarnings("serial")
上面添加注释。
如果你要序列化,那么你有很多事情要担心,所有的都围绕着正确使用UUID。 基本上,UUID是一种“版本化”你要序列化的对象的方法,以便任何进行反序列化的进程都知道它正确地反序列化。 我会看看确保序列化对象的正确版本控制了解更多信息。
只要有任何影响序列化的变化(附加字段,删除字段,字段顺序的变化…),就必须更改它。
这是不正确的,你将无法引用这个主张的权威来源。 只要您在“ 对象序列化规范” 的“序列化对象的版本控制”部分中给出的规则( 不包括附加字段或字段顺序的更改) 以及未提供readObject(), writeObject(),
时发生不兼容的更改readObject(), writeObject(),
和/或readResolve()
或/writeReplace()
方法和/或serializableFields
声明来处理更改。
任何可以序列化的类(即实现Serializable
)都应声明UID,并且只要有任何影响序列化的更改(附加字段,删除字段,字段顺序更改…)就必须更改它。 在反序列化过程中检查该字段的值,如果序列化对象的值不等于当前VM中的类的值,则会引发exception。
请注意,这个值是特殊的,因为它是与对象串行化的,即使它是静态的,由于上述原因。