当我想反序列化一个JTabbedPane时,我得到一个NullPointerException。
我的代码如下。
import javax.swing.*;
import java.io.*;
public class Bee {
public static void main(final String[] args) {
// --------- create tabbed pane
JTabbedPane tabbedPane = new JTabbedPane();
// ------------ Test serializing -------------------
final String file = "/tmp/swing.ser";
FileOutputStream fout = null;
ObjectOutputStream out = null;
FileInputStream fin = null;
ObjectInputStream oin = null;
try {
// ______________________ Write tabbedPane... _______________________
fout = new FileOutputStream(file);
out = new ObjectOutputStream(fout);
out.writeObject(tabbedPane);
out.close();
// ____________________________reading pane___________________
fin = new FileInputStream(file);
oin = new ObjectInputStream(fin);
final JTabbedPane readPane = (JTabbedPane) oin.readObject();
System.out.println("readPane: " + readPane.toString());
oin.close();
fin.close();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e2) {
e2.printStackTrace();
}
}
}
当我用OpenJDK运行这段代码时 8 9在Ubuntu 20.04上使用OpenJDK 11或Oracle JDK 14.0.1,以及在Win 10上使用OpenJDK 9和Oracle JDK 14(版本1909),我得到了以下或非常类似的stacktrace(这里,我展示了Ubuntu 20.04上Oracle JDK 14.0.1的输出)。
Exception in thread "main" java.lang.NullPointerException
at java.desktop/javax.swing.JTabbedPane.getTabCount(JTabbedPane.java:1118)
at java.desktop/javax.swing.plaf.basic.BasicTabbedPaneUI.installTabContainer(BasicTabbedPaneUI.java:308)
at java.desktop/javax.swing.plaf.basic.BasicTabbedPaneUI.installComponents(BasicTabbedPaneUI.java:304)
at java.desktop/javax.swing.plaf.basic.BasicTabbedPaneUI.installUI(BasicTabbedPaneUI.java:248)
at java.desktop/javax.swing.JComponent.setUI(JComponent.java:685)
at java.desktop/javax.swing.JTabbedPane.setUI(JTabbedPane.java:253)
at java.desktop/javax.swing.JTabbedPane.updateUI(JTabbedPane.java:269)
at java.desktop/javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1363)
at java.desktop/javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1354)
at java.desktop/javax.swing.JComponent$ReadObjectCallback.validateObject(JComponent.java:5457)
at java.base/java.io.ObjectInputStream$ValidationList$1.run(ObjectInputStream.java:2758)
at java.base/java.io.ObjectInputStream$ValidationList$1.run(ObjectInputStream.java:2756)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
at java.base/java.io.ObjectInputStream$ValidationList.doCallbacks(ObjectInputStream.java:2754)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:506)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:457)
at Bee.main(Bee.java:31)
我知道,将Swing对象序列化是个坏主意。但是,我所要做的代码大量使用了Java Swing的序列化功能。
因此,如果有人能指出我在反序列化JTabbedPane上所犯的错误,我会非常感激。
更新。 @GeorgeZ.的评论让我研究了不同的JDKs和OSs。JDK 8可以用 在Ubuntu 20.04(OpenJDK 1.8.0_252 -)上没有NullPointerException。违我原帖之意)和Win 10 build 1909 (OpenJDK 1.8.0_41)。JDK 9及以上版本 产生 NullPointerException (在Win10上:OpenJDK 9 build 9+181和Oracle JDK 14.0.1;在Ubuntu 20.04上:OpenJDK 9 build 9+181、OpenJDK 11.0.7和Oracle JDK 14.0.1)。OpenJDK 9 build 9+181,OpenJDK 11.0.7和Oracle JDK 14.0.1)。) 因此,这似乎是一个回归。
目前,在JDK 9和更新的版本中,包括JDK 15的早期访问版本,JTabbedPane不能被反序列化。
我提交了一个bug报告,您可以在以下网站找到它 https:/bugs.java.combugdatabaseview_bug.do?bug_id=JDK-8245785。.
作为一个变通方法,你可以