使用静态方法执行文件I / O时出现NotSerializableException

时间:2013-08-01 19:56:54

标签: java static io notserializableexception

所以,我有两个我声明为静态的类(通过使它们的方法保持静态,它们的构造函数是私有的),Synchronizer和UserProfile。 Synchronizer的saveData()函数调用UserProfile的saveData()函数:

private static void saveData(){
    UserProfile.saveData(data, dataFile);
}

这是UserProfile.saveData(...):

public static void saveData(Object obj, File file){
    try {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(obj);
        oos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Synchronizer和UserProfile都实现Serializable并具有自动生成的serialVersionUID。

有任何帮助吗?我很确定我在做一些根本错误的事情。

编辑:这是输出。

    Restoring sync data
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.jsoup.nodes.Document
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at java.util.ArrayList.readObject(ArrayList.java:733)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at UserProfile.restoreData(UserProfile.java:93)
    at Synchronizer.restoreData(Synchronizer.java:74)
    at Processor.<init>(Processor.java:8)
    at CommandLine.<init>(CommandLine.java:15)
    at TuneSnatch.main(TuneSnatch.java:5)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.io.NotSerializableException: org.jsoup.nodes.Document
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at java.util.ArrayList.writeObject(ArrayList.java:710)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at UserProfile.saveData(UserProfile.java:80)
    at Synchronizer.saveData(Synchronizer.java:87)
    at Synchronizer.addHTML(Synchronizer.java:44)
    at Processor.sync(Processor.java:100)
    at CommandLine.launch(CommandLine.java:99)
    at TuneSnatch.main(TuneSnatch.java:6)
    ... 5 more

4 个答案:

答案 0 :(得分:2)

此行中的对象obj

oos.writeObject(obj);

似乎是问题,而不是您的UserProfileSynchronizable类。我认为它不可序列化。从您的异常消息判断我认为它是org.jsoup.nodes.Document类型,它没有实现Serializable

答案 1 :(得分:1)

必须可序列化的不是用于序列化对象的类,而是序列化对象本身。在这种情况下,data(类型org.jsoup.nodes.Document)引用的对象必须是可序列化的,因为它是序列化并存储在文件中的此对象的状态。

使您的实用程序类可序列化没有意义:您永远不会创建它们的实例,因此永远不会序列化这些不存在的实例。

要进行类比,当你想发一封信时,你会在信上贴上一个印章,因为那就是发送的信。你的代码试图通过在邮递员上粘贴邮票来发送信件。

答案 2 :(得分:0)

正在抛出NotSerializableException,因为您尝试保存的某些数据(org.jsoup.nodes.Document)未实现Serializable。

确保您的数据对象实现Serializable,您的错误将消失。在这种情况下,这可能是不可能的,因为对象来自第三方库,因此您可能想要查看对象是否可以转换为另一种格式以进行序列化(Document可能具有某种类型的导出或转换方法)

您可以简单地调用Document.toString()来获取文档的serialiazable字符串表示形式,假设它生成一个可以由Jsoup.parse(String)读取的无损且适当可解析的字符串。

E.g。

public static void saveData(Document document, File file)
{
    String html = document.toString();
    ...
    oos.writeObject(html);
    ...
}

答案 3 :(得分:0)

用于执行序列化的类是可序列化的,这没有任何意义。您要保存到必须实现可序列化的文件的对象。您没有尝试保存实用程序类,只是使用它们来实现您尝试保留的对象的序列化。