需要帮助以了解 Java 中的 ArrayList 的反序列化

Need help to understand deserialization with ArrayList in Java

我想将 ArrayList 写入文件,然后再读回。该列表将包含 Integer 对象。序列化似乎工作正常,但我在反序列化时遇到了问题。更具体地说,我无法正确选角。

连载:

ObjectOutputStream ou =
    new ObjectOutputStream(new FileOutputStream(new File("load.dat")));

ArrayList<Integer> ouList = new ArrayList<>();
ou.writeObject(ouList);
ou.close();

反序列化:

ObjectInputStream in =
    new ObjectInputStream(new FileInputStrean("load.dat"));
ArrayList<Integer> inList = (ArrayList<Integer>)(in.readObject();
in.close();

当我编译时,我收到未经检查和不安全的警告。我使用 Xclint:unchecked 重新编译并收到以下消息:

warning: [unchecked] unchecked cast
    ArrayList<Integer> inList = (ArrayList<Integer>)(in.readObject());
                                                    ^
  required: ArrayList<Integer>
  found:    Object

我觉得这有点令人困惑:转换不是应该将对象转换为 arraylist 吗?为什么它需要 ArrayList 而这正是我要将其投射到的目标?在此先感谢您的帮助。

由于您收到 unchecked/unsafe 警告,我建议将它们放在 try/catch 块中。

这里有一个相对简单的教程,完全按照您的意愿执行:http://beginnersbook.com/2013/12/how-to-serialize-arraylist-in-java/

它告诉您编译器无法保证转换会在 运行 时间内成功 - 它可能会产生 ClassCastException

通常您可以使用 instanceof 检查类型以防止出现此警告,例如:

if (x instanceof ArrayList) {
    ArrayList y = (ArrayList) x; // No warning here 
}

很遗憾,instanceof 无法在 运行 时检查通用参数,因此您将无法安全地执行此操作。您所能做的就是取消警告。

但是如果你真的想确定集合的类型,那么你可以通过以下方式修改你的代码:

public class ArrayListOfIntegers extends ArrayList<Integer> {}

...

// writing:
ArrayListOfIntegers ouList = new ArrayListOfIntegers();
...
// reading:
ArrayListOfIntegers inList;
Object readData = in.readObject();
if (readData instanceof ArrayListOfIntegers) {
    inList = (ArrayListOfIntegers) readData;
} else {
    throw new RuntimeException("...");
}