有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

序列化Java:不可序列化异常

我正在用Java(类似俄罗斯方块)编写一个游戏,但在运行时出现了以下错误:

    java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.awt.image.BufferedImage
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.PoolPieces(Unknown Source)
at Fenetre.<init>(Fenetre.java:196)
at Score.lancerNewFenetre(Score.java:103)

所以这个错误发生在一开始,当我试图从服务器(类“Partie”(游戏))中检索一个“片段”数组时,然后设置片段并能够进行游戏。导致错误发生的代码是:

    try 
    {
        this.unpool = this.ninja.PoolPieces(this.id);
        System.out.println(unpool);
        this.setBoutons(this.unpool);
        System.out.println("boutons set");
    } 
    catch (RemoteException e) 
    {
        e.printStackTrace();
    }

它在第一行中断,其中“unpol”是一个片段[],“ninja”是我在代码开头设置的接口,“PoolPieces”是我获得3个片段(片段[])的池的方法。下面是“PoolPieces”方法的代码:

public Piece[] PoolPieces(Integer id) 
{
    Integer rang = this.listejoueurs[id].getRang(id);
    Integer retour = rang + 1;
    this.listejoueurs[id].setRang(retour);
    this.leretourpieces = this.piecespartie[rang];
    return this.leretourpieces;
}

我创建了一个类“jouer”(玩家),每个玩家都有一个“rang”(等级)。因此,所有玩家的可用棋子都是相同的,他们根据自己在游戏中的进展检索棋子池。 “ListJouers”是一个Jouer[],它是一个包含游戏中不同玩家的数组。 “id”是将客户端与播放器链接的标识符:添加的第一个播放器添加到数组中的位置0,id=0发送到客户端。下一个玩家的id=1,依此类推。 “leretourpiece”是我想要归还的作品[]。它取自游戏开始时随机创建的一块[][]。它是一个数组,三块数组的一个。“LeretoorPiece”根据玩家的进程获取棋子池(如上所述)

在互联网上查找错误后,我几乎在每个类中都实现了Serializable,但没有任何改变。奇怪的是,错误并没有出现,并且成功地获得了池,可能超过了10次,但是,当将碎片放入网格时,我遇到了sme问题、错位等(这可能是将碎片放入网格的代码中的错误,我不确定)

所以我被这个问题困住了,我找不到它的来源。提前非常感谢您花时间阅读本文,并最终帮助我:)


共 (2) 个答案

  1. # 1 楼答案

    因为你没有相关的代码块,所以很难给出明确的答案。在代码的某些部分中,您使用BufferedImage作为instance variable,并尝试将其序列化。只需找到相关的代码块并将其作为图像提供者带入方法体。(即getMyImage()

    如果您找不到解决方案,请在问题中添加相关代码块(使用BuffereImage),以便我可以更新我的答案

    **编辑**** 你能试试这个吗

    删除类Fenetre下面部分中的ImageIcon引用:

    private ImageIcon image1;
    private ImageIcon image2;
    private ImageIcon image3;   
    

    并替换此部分:

     this.image1 = new ImageIcon(this.getClass().getResource(this.nompiece1 + ".png"));
            this.image2 = new ImageIcon(this.getClass().getResource(this.nompiece2 + ".png"));
            this.image3 = new ImageIcon(this.getClass().getResource(this.nompiece3 + ".png"));
    

    与:

    ImageIcon image1 = new ImageIcon(this.getClass().getResource(this.nompiece1 + ".png"));
            ImageIcon image2 = new ImageIcon(this.getClass().getResource(this.nompiece2 + ".png"));
            ImageIcon image3 = new ImageIcon(this.getClass().getResource(this.nompiece3 + ".png"));
    
  2. # 2 楼答案

    您试图通过RMI操作的对象包含对BufferedImage的引用,并且正如错误消息所暗示的,java.awt.image.BufferedImage没有实现java.io.Serializable

    与Java的情况一样(不幸的是),最好远离所提供的可序列化机制,而不要提供您的机制

    (作为记录,Java设计者实际上后悔当初实现了它)

    否决票:由于否决票的速度比检查快,让我为您节省一些时间:观看Brian Goetz(Java语言架构师)的这张video,在20:59好好看一看“后悔序列化”的幻灯片,直到22:15左右

    对我们其余的人来说,有一些图书馆,比如Kryo,它们做得更好、更快、更安全