如何将未经检查的强制转换对象处理为 ArrayList<Vehicle>
How to address unchecked cast Object to ArrayList<Vehicle>
对于 class,我被分配编写代码以使用 ObjectInputStream (in
) 读取 class Vehicle
的对象。这些对象存储在名为 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);
}
根据我从阅读的内容中了解到的内容,它之所以有效,是因为如果不是所有元素都是 Vehicle
,(ArrayList<Vehicle>) obj
可能会抛出异常。我很困惑——非车辆对象可以添加到 ArrayList,即使其类型参数已指定为 Vehicle
?另外,有没有更好的解决方案,例如使用 instanceof
?
第一个代码使用泛型 (ArrayList) 摘录您的演员表
第二个代码摘录你的演员表没有通用。
cast 是运行时检查 - java 编译器会进行类型擦除,并且在运行时实际上两者之间没有区别
List<Vehicle>
和
List<Car>
你很接近。投射到 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);
}
如果您可以控制最初序列化的对象,则有一种方法可以完全避免循环:使用数组而不是集合。数组类型始终是安全的转换(如果它们本身没有泛型类型):
Object obj = in.readObject();
orders = new ArrayList<>(Arrays.asList((Vehicle[]) obj));
对于 class,我被分配编写代码以使用 ObjectInputStream (in
) 读取 class Vehicle
的对象。这些对象存储在名为 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);
}
根据我从阅读的内容中了解到的内容,它之所以有效,是因为如果不是所有元素都是 Vehicle
,(ArrayList<Vehicle>) obj
可能会抛出异常。我很困惑——非车辆对象可以添加到 ArrayList,即使其类型参数已指定为 Vehicle
?另外,有没有更好的解决方案,例如使用 instanceof
?
第一个代码使用泛型 (ArrayList) 摘录您的演员表
第二个代码摘录你的演员表没有通用。
cast 是运行时检查 - java 编译器会进行类型擦除,并且在运行时实际上两者之间没有区别
List<Vehicle>
和
List<Car>
你很接近。投射到 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);
}
如果您可以控制最初序列化的对象,则有一种方法可以完全避免循环:使用数组而不是集合。数组类型始终是安全的转换(如果它们本身没有泛型类型):
Object obj = in.readObject();
orders = new ArrayList<>(Arrays.asList((Vehicle[]) obj));