【问题标题】:NotSerializableException occuring where it shouldn'tNotSerializableException 发生在不应该发生的地方
【发布时间】:2016-08-16 01:25:44
【问题描述】:

我已经使用 Java 几个月了,但我对它还是很陌生,因此非常感谢任何帮助。我已经在一个游戏上工作了一段时间(基于另一个游戏)并且想制作一个关卡编辑器。我无法将信息保存到 .ser 文件中,即使我在其他类的其他地方执行此操作也没有问题。错误是java.io.NotSerializableException: resources.Sample$Ball,但它给我的行号与该类无关。我有一个名为 Sample 的类,其中有一个名为 Ball 的私有类,所以我明白这一点,但它为我提供信息的事实毫无意义。 Sample 类只在一个类中使用过一次,这不是我得到错误的那个。我从来没有遇到过这个类或 Ball 子类的问题,因为它们非常隐蔽而且很少用过。

错误给我的两个行号是: at LevelEditor.saveDialog(LevelEditor.java:309) at LevelEditor.actionPerformed(LevelEditor.java:256)

这些行号的代码行如下: oos.writeObject(new CustomSave(platforms, stars, ball, levelSize));

问题实际出现在哪里,而另一行号正是我调用上面代码所在函数的地方。CustomSave 类接受的变量仍然与@987654327 无关@ 或 Ball 类。因为CustomSave 类太小了,我也会在这里提供。我还将为上面的行号提供上下文。

代码上下文

try {
    File f = new File(filename);
    f.createNewFile();
    FileOutputStream fos = new FileOutputStream(f);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(new CustomSave(platforms, stars, ball, levelSize));
    oos.close();
} catch (Exception e1) {
    e1.printStackTrace();
}

自定义保存类

package resources;

import java.awt.Dimension;
import java.io.*;
import java.util.ArrayList;
import resources.BouncyBall;

public class CustomSave implements Serializable {
    private ArrayList<DragablePlatform> platforms;
    private ArrayList<StarPolygon> stars;

    private StaticBall ball;
    private Dimension levelSize;

    public CustomSave(ArrayList<DragablePlatform> platforms, ArrayList<StarPolygon> stars, StaticBall ball, Dimension levelSize){
        this.platforms = platforms; this.stars = stars; this.ball = ball; this.levelSize = levelSize;
    }

    public ArrayList<DragablePlatform> getPlatforms() {
        return platforms;
    }
    public ArrayList<StarPolygon> getStars() {
        return stars;
    }
    public BouncyBall getBall() {
        return ball;
    }
    public Dimension getLevelSize() {
        return levelSize;
    }
}

我也不知道为什么会出现这个错误,因为它没有任何意义。为了尝试进行故障排除,我尝试在 Ball 类中的 Ball 类上实现 Serializable Sample 并在一定程度上解决了问题。该错误停止将Sample$Ball列为问题,而是将另一个随机类列为问题,另一个与我正在尝试做的事情完全无关的类。

完全错误

java.io.NotSerializableException: resources.Sample$Ball
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeArray(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.access$300(Unknown Source)
at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
at java.io.ObjectOutputStream.writeFields(Unknown Source)
at java.awt.Container.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at LevelEditor.saveDialog(LevelEditor.java:454)
at LevelEditor.actionPerformed(LevelEditor.java:298)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

关卡编辑器第 454 行

oos.writeObject(new CustomSave(platforms, stars, ball, levelSize));

关卡编辑器第 298 行

saveDialog();(包含上述行的函数)

非常感谢所有帮助,如果您需要其他任何帮助,请随时提出。

谢谢。

【问题讨论】:

  • f.createNewFile(); 在这里毫无意义。 new FileOutputStream() 已经这样做了,所以你强制它删除你刚刚创建的文件并创建另一个文件。在某个地方,您引用了正在序列化的 Ball 类。堆栈跟踪来自writeObject() 调用,而不是它找到的不可序列化的类。
  • 如果StaticBallDimension 不可序列化,或者这些类中的任何一个包含对不可序列化类的引用,您将收到此错误。由于您没有显示代码,我们无法提供真正的帮助。您必须遵循正在序列化的主对象的所有引用链。如果您愿意提供必要的详细信息,例如错误消息和完整的堆栈跟踪以及所有相关代码,它可能会有所帮助。
  • @JimGarrison Static Ball 是可序列化的,但它扩展的类不是。因为当我确实使该类可序列化时,我得到了上面的错误(我现在发布了完整的错误)。我通过从扩展类中删除 implements Serializable 来“修复”这个问题,但现在我需要该类是可序列化的。

标签: java notserializableexception


【解决方案1】:

要正确进行序列化,您必须确保要序列化的所有类都实现 Serializable 接口,一旦我尝试一次保存一个对象并查看导致问题的对象时,我遇到了同样的问题 - 冲洗 oos。

try {        
    FileOutputStream fos = new FileOutputStream(new File(filename));
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(platforms);
    oos.writeObject(stars);
    oos.writeObject(balls);
    oos.writeObject(levelSize);
    oos.flush();
    oos.close();
}catch (Exception e1) {
    e1.printStackTrace();
}

【讨论】:

  • flush()close() 之前是多余的。
【解决方案2】:

要使序列化/反序列化成功,必须满足以下两个条件:

  1. 您要序列化/反序列化的类必须实现 java.io.Serializable 界面。
  2. 该类中的所有字段必须是原始类型或必须实现 java.io.Serializable接口。

条件 1(满足):因为 CustomSave implements Serializable

条件 2 (?):StaticBallDragablePlatformStarPolygon 是否实现 Serializable?

private ArrayList<DragablePlatform> platforms; // ArrayList implements Serializable? Yes, DragablePlatform implements Serializable?
private ArrayList<StarPolygon> stars; // ArrayList implements Serializable? Yes, StartPolygon implements Serializable?
private StaticBall ball; // StaticBall implements Serializable?
private Dimension levelSize; // Dimension implements Serializable? Yes

【讨论】:

  • 如你所说,满足条件 1,我检查了所有其他类,我让它们都实现了可序列化。即使其中一个没有,我也不明白为什么它会给我Sample 中的Ball 类作为错误。至于你上面的答案,我都是独立完成的,我得到的错误是 StaticBall。
  • 看来我只是不小心把它修好了。 StaticBall 类正在扩展另一个类。该类也实现了 Serializable。当我注意到这一点时,出于好奇,我摆脱了它并修复了它。为什么这会是问题,为什么当其他随机类实际上与问题无关并且与问题类没有直接关系时,它会开始将其他随机类识别为问题?无论如何,感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多