【问题标题】:Serializing an object which contains a list of other objects序列化包含其他对象列表的对象
【发布时间】:2015-06-11 04:03:03
【问题描述】:

背景:我正在实现一个需要序列化模型对象(事件)的游戏,以便能够通过网络将它们发送给玩游戏的客户端。

问题:我的模型类之一是EventShowCards,它是Event 的子类(声明为可序列化)。

public class EventShowCards extends Event {
    private final Player player;
    private final List<ItemCard> cards;

    public EventShowCards(Player player, List<ItemCard> cards) {
        super();
        this.player = player;
        this.cards = cards;
    }

    public Player getPlayer() {
        return player;
    }

    public List<ItemCard> getCards() {
        return cards;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

但是,当我序列化对象并将其发送给客户端时,客户端接收到对象并且ItemCards 的列表为空。 不抛出异常

服务器显示的事件(序列化之前):

客户端显示的事件(序列化后):

为了序列化/反序列化,我使用标准的 ObjectOutputStream/ObjectInputStream

有人知道这里会发生什么吗?谢谢。

编辑

根据要求,我发布了 ItemCard(和卡)的代码:

ItemCard.java

public abstract class ItemCard extends Card {

    /**
     * By default a card ca be played independently from the game state, subclasses that have more complicated rules
     * must override this method.
     */
    public boolean canBePlayed(GameStateTurn gameState) {
        return true;
    }

    protected void emitEventCardPlayed(Player cardPlayer, GameState gameState)  {
        notifyObservers(new EventCardPlayed(cardPlayer, this));
    }

}

Card.java

public abstract class Card extends ConcreteObservable<Event> implements CardBehavior, Serializable {
    protected Deck<? extends Card> deck; // The deck to which this card belongs

    public Card() {
        super();
    }

    public void setDeck(Deck<? extends Card> deck) {
        this.deck = deck;
    }

    public void discard() {
        deck.discard(this);
    }

    @Override
    public void preEffect(Player cardPlayer, GameState gameState) {
        // By default cards have no preEffects
    }

    @Override
    public void postEffect(Player cardPlayer, GameState gameState) {
        // By default after a card is played it is discarded
        discard();
    }

    @Override
    public String toString() {
        String className = this.getClass().getSimpleName();
        return cardNameFromClassName(className);
    }

    private String cardNameFromClassName(String className) {
        StringBuilder sb = new StringBuilder();
        for (Character c: className.toCharArray()) {
            if (Character.isUpperCase(c)) {
                sb.append(" ").append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return "\"" + sb.substring(1) + "\"";
    }
}

编辑 2

Deck.java

public class Deck<T extends Card>
        extends ConcreteObservable<Event>
        implements Observer<Event>, Serializable {...}

编辑 3

用于初始化 EventShowCards 的项目卡列表是从我的应用程序的另一个模型对象创建的列表,按原样传递。创建另一个 ArrayList(复制该对象)以某种方式解决了我的问题。

【问题讨论】:

  • LIste 元素是否可序列化?他们实现了 Serializable 接口吗?
  • 是的,卡是可序列化的

标签: java sockets serialization


【解决方案1】:

列表可以包含无限数量的对象类型。
由于您已将 EventShowCards 序列化(通过 Event 类),因此您还需要强制您的 ItemCardclass 可序列化,以便在需要时正确编组和解组。

编辑

java.util.List 没有实现 Serializable,这就是你的列表没有序列化的原因。
使用其他可序列化的集合,例如ArrayList

【讨论】:

  • 事实是我的 ItemCard 对象声明自己是可序列化的(公共抽象类 ItemCard 扩展 Card 实现 Serializable {...})...除此之外我还需要做什么吗?
  • java.util.List 没有实现 Serializable,这就是你的列表没有序列化的原因
  • 在这种特殊情况下使用的底层类型是实现 Serializable 的 ArrayList
  • 但是声明为列表,改一下再试
  • 我认为你错了...我以这种方式序列化的另一个对象有一个 Map 字段并且可以很好地序列化... Map 不可序列化(如 List),但使用的对象的实际类型(HashMap)是。事实上,对象被序列化就好了。
猜你喜欢
  • 2018-03-20
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 1970-01-01
相关资源
最近更新 更多