![](/img/trans.png)
[英]java generics - cast to List<SomeType> issues unchecked cast warning while cast to SomeType not
[英]Unchecked cast warning with Java Generics, type parameter, and returned list
从更复杂的类结构中,我尽可能地简化了这段代码。 在实际的代码中,我在这里使用了Integer和Double类型的子类型。
我正在尝试使用带有类型参数的Java泛型。 如果用户请求Number.class
的类型,我们希望将List<Integer>
列表和List<Double>
列表合并为一个列表。
代码正常工作时,我无法摆脱未经检查的强制转换警告(请参阅TODO标签)。 警告是:
Type safety: Unchecked cast from List<Integer> to Collection<? extends T>
但是,如果删除强制类型转换,则会出现编译错误:
The method addAll(Collection<? extends T>) in the type List<T> is not applicable for the arguments (List<Integer>).
我的代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class Generics1 {
static final List<Integer> intList = new ArrayList<Integer>(Arrays.asList(
1, 2, 3, 4));
static final List<Double> dblList = new ArrayList<Double>(Arrays.asList(
1.1, 2.2, 3.3));
public static <T extends Number> List<T> getObjects(Class<T> type) {
List<T> outList = new ArrayList<T>();
if (type == Number.class) {
// user asked for everything
// TODO: unchecked cast warnings here should be fixed
outList.addAll((Collection<? extends T>) intList);
outList.addAll((Collection<? extends T>) dblList);
} else {
// user asked for subtype of number
if (Integer.class.isAssignableFrom(type)) for (Integer i : intList)
if (type.isInstance(i)) {
T obj = type.cast(i);
outList.add(obj);
}
if (Double.class.isAssignableFrom(type)) for (Double d : dblList)
if (type.isInstance(d)) {
T obj = type.cast(d);
outList.add(obj);
}
}
return outList;
}
public static void main(String[] args) {
System.out.println("HI!");
System.out.println("integers: " + getObjects(Integer.class));
System.out.println("doubles: " + getObjects(Double.class));
System.out.println("numbers: " + getObjects(Number.class));
}
}
您可以将其添加到您的代码中:
@SuppressWarnings("unchecked")
这是另一篇SO帖子,解释“ what”的意思: Java中的SuppressWarnings(“ unchecked”)是什么?
这是另一个可能有用的链接转换方法: 如何解决“类型为List的表达式需要未经检查的转换...”?
尽管通过一些重新编码,您可能可以使警告完全消失,并且不需要被抑制。
(先前的答案已删除)
这是使用Guava做到这一点的一种方法:
@SuppressWarnings("unchecked")
public static <T> List<T> filterAndCollapse(final Class<T> type,
Collection<?> a, Collection<?> b) {
List combined = new ArrayList();
Predicate<Object> filter = new Predicate<Object>() {
public boolean apply(Object obj) {
return type.isInstance(obj);
}
};
combined.addAll(Collections2.filter(a, filter));
combined.addAll(Collections2.filter(b, filter));
return combined;
}
// ...
filter(Number.class, intList, dblList);
编辑:比较的全类型安全方法。
public static <T> List<T> filterAndCollapse(final Class<T> type,
Collection<?> a, Collection<?> b) {
List<T> combined = new ArrayList<T>();
Predicate<Object> filter = new Predicate<Object>() {
public boolean apply(Object obj) {
return type.isInstance(obj);
}
};
Function<Object, T> transform = new Function<Object, T>() {
public T apply(Object obj) {
return type.cast(obj);
}
};
combined.addAll(Collections2.transform(Collections2.filter(a, filter),
transform));
combined.addAll(Collections2.transform(Collections2.filter(b, filter),
transform));
return combined;
}
不幸的是,据我所知,无法使用Guava一步进行过滤和转换。
(Class<T> type)
List<T> outList = new ArrayList<T>();
if (type == Number.class) {
// obviously, T==Number here, though the compiler doesn't know that
// so we do the cast. compiler will still warn. since the cast makes
// perfect sense and is obviously correct, we are ok with it.
List<Number> numList = (List<Number>)outList;
numList.addAll( intList);
numList.addAll( dblList);
} else {
更好的解决方案
for list in lists
for item in list
if item instance of type
add item to result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.