【问题标题】:ArrayList empty after being serialized only if not directly assignedArrayList 只有在没有直接赋值的情况下才被序列化后为空
【发布时间】:2017-12-06 15:55:10
【问题描述】:

在发送/接收包含 ArrayList 的 Serializable 对象时遇到问题。我有一个类 Robot,看起来像这样:

public class Robot {
    private ArrayList<InstructionCard> pool;
    /*other fields... */

    public void refillPool(Deck deck) {
        int nCards = this.healthPoints - this.pool.size();
        if(nCards >= 1) {
            ArrayList<InstructionCard> cards = deck.draw(nCards);
            //we add the cards to the old pool
            for(int i = 0; i < cards.size(); i++) {
                this.pool.add(cards.get(i)); // A
            }
            //pool = cards;  //REPLACE THE FOR LOOP WITH THIS LINE DOES THE JOB
        }
    }

    public RobotInfo getInfo(){
       return new RobotInfo(this.pool);
    }
}

我使用包含在 Robot 对象中的信息来创建一个可序列化的对象 RobotInfo,通过连接发送:

public class RobotInfo implements Serializable {
     private ArrayList<InstructionCard> pool;

     public RobotInfo(ArrayList<InstructionCard> p) {
         pool = p;
     }
}

但是,当我收到这样的对象时,池是一个空的 ArrayList。 InstructionCard implements Serializable 也是如此,它只包含一个 int 和一个 String 字段。

我做了一些测试,我确信在发送 RobotInfo 对象之前,它的 pool.size() 不是 0

但是,当我收到包含它的消息时,pool.size() returns 0,除非(这是我完全不明白的)我将 refillPool() 方法中的 for 循环替换为直接赋值。

我相信我在 A 点的 InstructionCard 引用一定有问题(对我来说,这似乎不是与 Serializable 相关的问题)。

真正的问题是为什么RobotInfo 中的池在两种情况下都不是空的,而是只有在我使用 for 循环时才变为空?

编辑:我能够做出一个临时解决方法,将 ArrayList&lt;InstructionCard&gt; 替换为 ArrayList&lt;String&gt;,每次我需要发送 RobotInfo 对象时都重新创建它。这不知何故让我认为这只是某种参考问题。

【问题讨论】:

  • 如果您使用循环 (A),如何初始化池列表以使其不为空?此外,您可以使用现有的 addAll 方法,而不是使用循环添加所有元素。
  • 我省略了 Robot 的构造函数,它将池初始化为一个新的、空的 ArrayList。感谢 addAll() 提示。当我遇到问题时,我会尽我所能“手动”揭露逻辑缺陷
  • 我提出了一个“猜测”的答案。如果它对您不起作用 - 花一些时间阅读有关 minimal reproducible example 的内容,然后改进您的问题 不要用 10 行来解释代码在做什么 - 尝试提出一个 minimal 代码示例导致问题。如果您对代码的理解/假设都与您的代码的功能相匹配……您就不会在这里要求我们帮助您解决您在某个地方遇到的错误!
  • 我完全同意你的观点,用这么少的代码信息很难找到问题。如果不是因为时间不够,我很想从头开始编写一些测试来了解发生了什么。

标签: java arraylist reference serializable


【解决方案1】:

我在这里猜测

private ArrayList<InstructionCard> pool;

离开 poolnull

所以这段代码:

pool = cards; 

会将非空引用放入池中。

另一方面;这意味着cards.size() 实际上是0;因为你会在这里遇到NullPointerException

for(int i = 0; i < cards.size(); i++){
 this.pool.add(cards.get(i));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2016-11-12
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多