【问题标题】:Java - Serialization - NotSerializableException IssueJava - 序列化 - NotSerializableException 问题
【发布时间】:2014-09-09 13:00:29
【问题描述】:

我目前正在仅使用 Java 开发一个学生数据库,并且有两个我想保存的特定列表。学生和个人资料(登录时使用)。我目前正在对学生进行序列化测试,只是为了让它工作,但遇到了一个奇怪的问题。


我的学生对象类和代码如下:

学生.java

StudentsCollection.java

Students 创建我的 Student 对象(自我解释),并且我的 StudentsCollection() 实例化一个 Student 类型的列表,该列表存储我的 Student 对象,当我尝试保存/加载对象时,我使用此代码并引发以下异常:

    /**
     * Save student collection
     */
   public void saveCollection(){
      try {
         FileOutputStream e = new FileOutputStream("students.ser");
         ObjectOutputStream outputStream = new ObjectOutputStream(e);
         for(Students i : this.list){
             outputStream.writeObject(i);
         }
         outputStream.flush();
         outputStream.close();
      } catch (IOException var3) {
          var3.printStackTrace();
         JOptionPane.showMessageDialog((Component)null, "Error. Cannot save database.");
      }

   }

    /**
     * Open student collection
     */
   public void openCollection(){
      try {
         FileInputStream e = new FileInputStream("students.ser");
         ObjectInputStream inputSteam = new ObjectInputStream(e);
          while(inputSteam.readObject() != null){
              this.list.add((Students)inputSteam.readObject());
          }
      } catch (FileNotFoundException var3) {
          var3.printStackTrace();
         JOptionPane.showMessageDialog(null, "File not found");
      } catch (IOException var4) {
          var4.printStackTrace();
         JOptionPane.showMessageDialog(null, "IO Exception");
      } catch (ClassNotFoundException var5) {
          var5.printStackTrace();
         JOptionPane.showMessageDialog(null, "Required class not found");
      }

   }

并打印以下异常:

java.io.NotSerializableException: java.util.Scanner
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at jdatabase.objects.students.StudentsCollection.saveCollection(StudentsCollection.java:539)
at jdatabase.main.MainController$1.run(MainController.java:22)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

我还想指出,students.ser 实际上是在我的项目资源管理器中创建的,但仍然抛出异常,即使尝试使用 openCollection() 也会抛出错误,但是我想解决 saveCollection()首先正确

【问题讨论】:

  • 我在您的代码 sn-ps 中看不到它,但错误看起来好像它正在尝试序列化扫描仪。您的学生班级是否有任何机会将扫描仪作为字段?
  • 你说得对,一旦我失去了我的项目,我让朋友反编译了我的 JAR 并且一些代码混乱了,默认构造函数出于某种原因请求输入学生姓名.. 会尝试删除所有扫描仪,看看它是否有效
  • 你的班级有Scanner字段吗?
  • 是的,我找到了问题所在。谢谢!

标签: java serialization io


【解决方案1】:

在您的this.list 中有一个Object Students,它引用了Scanner。删除引用,你会没事的。

【讨论】:

    【解决方案2】:

    你没有发布你的Student.java,所以我在这里猜。 Student 类中是否有 java.util.Scanner 类型的字段?有的话删掉,或者标记为transient

    private transient Scanner someField;
    

    transient 修饰符将阻止字段被序列化。

    【讨论】:

    • 您可以添加一些信息,transient 使用此修饰符防止字段序列化。
    • 是的,当我的项目被反编译时(前段时间丢失了源代码),它导致了一些奇怪的代码,我所有的构造函数都有一些扫描器出于某种原因请求输入
    【解决方案3】:

    只有当对象的所有类成员都实现了 Serializable 时,才能序列化对象。 正如 RobAu 所说,Scanner 是不可序列化的。

    你可以在这里找到一个很好的教程:http://www.vogella.com/tutorials/JavaSerialization/article.html

    所有标记有瞬态的字段都不会被序列化。有关更多详细信息,请参见此处: How does marking a field as transient make it possible to serialise an object

    【讨论】:

    • 是的,我知道这一点,不知道 Scanner 对象甚至在那里,这就是为什么在阅读堆栈跟踪时我有点困惑!
    【解决方案4】:

    由于scanner类没有实现Serializable接口,你的类中肯定有一些字段要求通过scanner进行输入,因此报错。

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 2014-09-09
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      相关资源
      最近更新 更多