3

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

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>) obj如果不是所有元素都是Vehicle. 我很困惑 - 非车辆对象可以添加到 ArrayList 即使其类型参数已指定为Vehicle?此外,是否有更好的解决方案,例如使用instanceof

4

2 回答 2

5

你很亲密。强制转换为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));
于 2017-12-30T01:51:26.597 回答
1

第一个代码用泛型(ArrayList)摘录你的演员第二个代码摘录你的演员没有泛型。cast 是运行时检查 - java 编译器会进行类型擦除,并且在运行时实际上 a List<Vehicle>List<Car>

于 2017-12-30T01:07:03.243 回答