如何将未经检查的强制转换对象解析为ArrayList

问题描述 投票:1回答:2

对于类,我被分配编写代码以使用ObjectInputStream(Vehicle)读取类in的对象。对象存储在名为orders的ArrayList中。

SSCE:

// Read all orders
Object obj = in.readObject();
orders = (ArrayList<Vehicle>) obj;

但是,编译器抱怨:

MacBook:Homework Brienna$ javac Orders.java -Xlint:unchecked
Orders.java:152: warning: [unchecked] unchecked cast
                    orders = (ArrayList<Vehicle>) in.readObject();
                                                                ^
  required: ArrayList<Vehicle>
  found:    Object
1 warning

我总是试图改进我的代码,而不是忽略或抑制警告。在这种情况下,我想出了一个解决方案,但我试图理解它为什么会起作用,以及是否有更好的解决方案。

此更新会停止警告:

// Read all orders, casting each order individually
Object obj = in.readObject();
ArrayList ar = (ArrayList) obj;
for (Object x : ar) {
    orders.add((Vehicle) x);
}

基于我从我所阅读的内容中理解的内容,它起作用,因为如果不是所有元素都是(ArrayList<Vehicle>) objVehicle可能会抛出异常。我很困惑 - 即使将其类型参数指定为Vehicle,也可以将非Vehicle对象添加到ArrayList中?此外,是否有更好的解决方案,例如使用instanceof

java arraylist casting compiler-warnings unchecked-cast
2个回答
3
投票

你很亲密投射到ArrayList<?>总是安全的:

Object obj = in.readObject();
ArrayList<?> ar = (ArrayList<?>) obj;

orders.clear();
for (Object x : ar) {
    orders.add((Vehicle) x);
}

你甚至可能想要更加安全并投射到更通用的东西,比如Iterable:

Object obj = in.readObject();
Iterable<?> ar = (Iterable<?>) obj;

orders = new ArrayList<>();
for (Object x : ar) {
    orders.add((Vehicle) x);
}

如果您可以控制最初序列化的对象,则可以完全避免循环:使用数组而不是Collection。数组类型始终是安全的转换(如果它们本身没有泛型类型):

Object obj = in.readObject();
orders = new ArrayList<>(Arrays.asList((Vehicle[]) obj));

1
投票

第一个代码摘录你的演员与通用(ArrayList)第二个代码摘录你的演员没有通用。 cast是运行时检查 - java编译器确实键入擦除,并且在运行时实际上List<Vehicle>List<Car>之间没有区别

© www.soinside.com 2019 - 2024. All rights reserved.