How to safely convert from a Collection of generic types to an array?
本问题已经有最佳答案,请猛点这里访问。
出于各种原因,我希望将列表转换为数组,但是集合包含本身是泛型的对象。
我尝试了以下四个选项来编译它,而不需要@supressWarnings("unchecked")注释,但它们都不起作用。是否有解决方案可以使此正确工作,或者强制使用注释?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Iterator<T>[] iterators; final Collection<Iterator<T>> initIterators = new ArrayList<Iterator<T>>(); // Type safety: Unchecked cast from Iterator[] to Iterator<T>[] iterators = initIterators.<Iterator<T>>toArray( (Iterator<T>[])new Iterator[initIterators.size()]); // Type safety: Unchecked invocation toArray(Iterator[]) of the generic // method toArray(T[]) of type Collection<Iterator<T>> // Type safety: The expression of type Iterator[] needs unchecked conversion // to conform to Iterator<T>[] iterators = initIterators.<Iterator<T>>toArray( new Iterator[initIterators.size()]); // Type safety: The expression of type Iterator[] needs unchecked conversion // to conform to Iterator<T>[] iterators = initIterators.toArray(new Iterator[initIterators.size()]); // Doesn't compile iterators = initIterators.toArray(new Iterator<T>[initIterators.size()]); |
没有类型安全的方法来创建参数化类型的数组,如
或者,您可以创建一个原始数组:
不可能的原因是Java数组是协变的,泛型类型的参数化边界是不变的。这就是说:
1 2 3 |
由于
对于泛型,参数化类型是不同的。首先,由于编译时类型擦除,它们本质上不知道自己的运行时类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | List<Integer> integerList = new ArrayList<Integer>(); List<Number> numberList = integerList; // compiler error, prevents: numberList.add(new Double(3.14)); // would insert a Double into integerList Collection<Integer> integerCollection = integerList; // allowed // OK because List extends Collection and the <type parameter> did not change Collection<Number> numberCollection = integerList; // compiler error // an"Integer" is a"Number" // but"a collection of Integers" is more specific than"a collection of Numbers" // and cannot be generally treated the same way and guarantee correct behavior List<?> rawList = integerList; // allowed, but... rawList.add(new Integer(42)); // compiler error, Integer is not a ... a what? |
对于泛型,在Java中,您依赖编译器(而不是运行时)来验证泛型类型是否正确和安全。
因此,虽然