【问题标题】:Java : not Serializable Exception [duplicate]Java:不可序列化异常[重复]
【发布时间】:2016-06-06 20:35:38
【问题描述】:

我正在用 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”(游戏))检索“Piece”数组时,然后设置碎片并能够播放。导致错误发生的代码是:

    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();
    }

它在第一行中断,其中“unpool”是一个 Piece[],“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;
}

我创建了一个类“Joueur”(玩家),每个玩家都有一个“rang”(等级)。因此,所有玩家的可用棋子都是相同的,他们会根据自己在游戏中的进展来取回棋子池。 “listejoueurs”是一个 Joueur[],它是一个包含游戏不同玩家的数组。 “id”是连接客户端和播放器的标识符:添加的第一个播放器被添加到数组中的位置 0,并且 id = 0 被发送到客户端。下一个玩家的 id = 1,依此类推。 “leretourpiece”是我想要返回的 Piece[]。它取自 Piece[][],在游戏开始时随机创建。它是一个数组,由 3 Piece 组成。 "leretourpiece" 根据玩家的进度获取棋子池(如上所述)。

在互联网上查找该错误后,我几乎在每个课程中都实现了 Serializable,但没有任何改变。奇怪的是,错误没有出现,并且成功地获得了池,也许一次超过 10 个意图左右,但是,当把棋子放在网格上时,我遇到了一些问题,错位等等。(这可能是在网格上放置一块的代码中的错误,我不确定)。

所以我很纠结这个问题,我找不到它的来源。非常感谢您花时间阅读本文,并最终帮助我:)

【问题讨论】:

  • 好的,我做了你建议的改变,但仍然出现同样的错误:/

标签: java serialization


【解决方案1】:

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

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

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

删除 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"));

【讨论】:

  • 这里是代码的主要部分(ActionListner除外,因为它很长,我不认为它是错误的根源):
  • pastebin.com/pbNDqvtV(评论太长了)
  • “Partie”(游戏类)代码:
  • @AlexandrevanWesel 你能检查我的编辑并再试一次吗?
【解决方案2】:

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

正如(不幸地)Java 经常发生的情况一样,最好远离提供的 Serializable 机制,而是提供你自己的。

(据记录,Java 设计者实际上很遗憾一开始就实现了它)

Downvoters:由于您的投票速度比您检查的速度快,所以让我为您节省一些时间:观看 Brian Goetz(Java 语言架构师)的 video 并在 20:59 好好看看幻灯片上写着“后悔连载”,听到大约 22:15。

对于我们其他人来说,有一些库,例如 Kryo,它做得更好、更快、更安全。

【讨论】:

  • 我会尽快尝试并给你反馈。
  • 请引用您对 Java 设计者的声明。
  • @EJP 现在你可以把我的 2 分还给我 :)
  • @EJP 这个问题不是重复的,因为我不尝试序列化 BufferImage。它是直接在客户端完成的,所以应该没有任何问题。此外,在您发布的线程中,明确指出 ImageIcon 是可序列化的,这就是我使用的...
猜你喜欢
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 2017-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多