这段代码无法编译,有什么建议可以提供吗?
...
List<Object> list = getList();
return (List<Customer>) list;
编译器报错:无法将 List<Object>
强制转换为 List<Customer>
正如其他人所指出的那样,您不能安全地对它们进行强制转换,因为 List<Object>
并不是 List<Customer>
。您可以定义一个视图来进行就地类型检查。使用 Google Collections 可以实现:
return Lists.transform(list, new Function<Object, Customer>() {
public Customer apply(Object from) {
if (from instanceof Customer) {
return (Customer)from;
}
return null; // or throw an exception, or do something else that makes sense.
}
});
List<Object>
和List<Customer>
不在同一继承树中。List<Customer>
类中添加一个新的构造函数,该构造函数接受一个List<Object>
,然后遍历列表,将每个Object
强制转换为Customer
并将其添加到您的集合中。请注意,如果调用者的List<Object>
包含不是Customer
的内容,则可能会发生无效的强制转换异常。最简单的解决方案是使用
(((List<Object>)(List<?>) yourCustomClassList))
和上面的Bozho类似。你可以通过以下方法进行一些变通(尽管我自己不喜欢):
public <T> List<T> convert(List list, T t){
return list;
}
是的。它会将您的列表转换为所需的泛型类型。
在上述给定情况下,您可以编写以下代码:
List<Object> list = getList();
return convert(list, new Customer());
你最好的选择是创建一个新的List<Customer>
,遍历List<Object>
,将每个项目添加到新列表中,并返回该列表。
根据您想要对列表执行的操作,您甚至可能不需要将其转换为List<Customer>
。如果您只想向列表中添加Customer
对象,则可以声明如下:
...
List<Object> list = getList();
return (List<? super Customer>) list;
这是合法的(不仅仅是合法的,而且是正确的 - 列表是“某些超类型到Customer”的),如果你要将其传递给仅会向列表中添加对象的方法,则上述通用边界就足够了。
另一方面,如果你想从列表中检索对象并将它们强类型为Customers - 那么你就没那么幸运了,而且这是正确的。因为列表是 List<Object>
,所以不能保证内容是客户,因此您将需要在检索时提供自己的转换。(或非常,绝对地确保列表仅包含 Customers
并使用其他答案之一的双重转换,但请意识到,在这种情况下,您完全可以绕过泛型编译时类型安全)。
广义上讲,在编写方法时,考虑到最广泛的通用边界总是有益的,尤其是如果它将被用作库方法。例如,如果您只打算从列表中读取,请使用List<? extends T>
而不是List<T>
,这样可以为调用者提供更多的参数范围,并意味着他们不太可能遇到类似于此处所遇到的可避免问题。
List<Object[]> testNovedads = crudService.createNativeQuery(
"SELECT ID_NOVEDAD_PK, OBSERVACIONES, ID_SOLICITUD_PAGO_FK FROM DBSEGUIMIENTO.SC_NOVEDADES WHERE ID_NOVEDAD_PK < 2000");
Convertir<TestNovedad> convertir = new Convertir<TestNovedad>();
Collection<TestNovedad> novedads = convertir.toList(testNovedads, TestNovedad.class);
for (TestNovedad testNovedad : novedads) {
System.out.println(testNovedad.toString());
}
public Collection<T> toList(List<Object[]> objects, Class<T> type) {
Gson gson = new Gson();
JSONObject jsonObject = new JSONObject();
Collection<T> collection = new ArrayList<>();
Field[] fields = TestNovedad.class.getDeclaredFields();
for (Object[] object : objects) {
int pos = 0;
for (Field field : fields) {
jsonObject.put(field.getName(), object[pos++]);
}
collection.add(gson.fromJson(jsonObject.toString(), type));
}
return collection;
}