java - How to safely convert from a Collection of generic types to an array? -
this question has answer here:
- how create generic array in java? 27 answers
- array of generic list 5 answers
for various reasons want convert list array, collection contains objects generics.
i have tried following 4 options compile without needing @supresswarnings('unchecked') annotation, none of them work. there solution make work correctly, or forced use annotation?
iterator<t>[] iterators; final collection<iterator<t>> inititerators = new arraylist<iterator<t>>(); // type safety: unchecked cast iterator[] iterator<t>[] iterators = inititerators.<iterator<t>>toarray( (iterator<t>[])new iterator[inititerators.size()]); // type safety: unchecked invocation toarray(iterator[]) of generic // method toarray(t[]) of type collection<iterator<t>> // type safety: expression of type iterator[] needs unchecked conversion // conform iterator<t>[] iterators = inititerators.<iterator<t>>toarray( new iterator[inititerators.size()]); // type safety: expression of type iterator[] needs unchecked conversion // conform iterator<t>[] iterators = inititerators.toarray(new iterator[inititerators.size()]); // doesn't compile iterators = inititerators.toarray(new iterator<t>[inititerators.size()]);
there no type-safe way create array of parameterized type such iterator<t>[]
.
alternatively, can create raw array: iterator<?>[]
. or, if can avoid use of arrays entirely, use collection type list<iterator<t>>
.
the reason not possible java arrays covariant , parameterized bounds of generic types invariant. say:
integer[] integers = new integer[1]; number[] numbers = integers; // ok because integer extends number numbers[0] = new double(3.14); // runtime exception
the compiler allows assignment because double
extends number
, declared type of numbers
number[]
. @ runtime actual array object instance original integer[1]
, arrays know type of objects contain.
with generics, parameterized types different. one, due compile-time type erasure not intrinsically know runtime types.
list<integer> integerlist = new arraylist<integer>(); list<number> numberlist = integerlist; // compiler error, prevents: numberlist.add(new double(3.14)); // insert double integerlist collection<integer> integercollection = integerlist; // allowed // ok because list extends collection , <type parameter> did not change collection<number> numbercollection = integerlist; // compiler error // "integer" "number" // "a collection of integers" more specific "a collection of numbers" // , cannot treated same way , guarantee correct behavior list<?> rawlist = integerlist; // allowed, but... rawlist.add(new integer(42)); // compiler error, integer not ... what?
with generics, in java, relying on compiler (not runtime) validate generic types correct , safe.
so while iterator<?>[]
knows @ runtime array contains iterator
elements, <t>
in iterator<t>[]
erased @ compile time , runtime has no way know supposed be. unchecked warning.
Comments
Post a Comment