java - array of wildcard collection initialized with array of rawtype -
reasonably enough, compiler give raw type conversion warning this:
//1 list<?> arrlist = new arraylist(); //raw type warning
however, compiler ok (no warning) line:
//2 list<?>[] arr_of_arrlist = new arraylist[3];// no warning, why ?
so, without complains compiler further do:
arr_of_arrlist[0] = new arraylist<string>(); arr_of_arrlist[1] = new arraylist<integer>();
could please explain why given array initialization (2) considered type-safe opposed first list initialization (1) , compiler doing in case 2.
the compiler warn when defining:
list<string>[] foo = new arraylist[3];
this because warning, compiler trys make aware lists stored in list<string>[] foo
possibly not of generic type string
. end list<integer>
in foo
@ run time:
void main(){ list<string>[] array = new list[1]; fill(array); // compiler not check array @ compile time, // next line permitted. created time bomb. list<string> list = array[0]; // next line cause classcastexception @ runtime! // luck debugging, if have passed list // arround while. // if had defined list<?>[] foo, assignment have been // forbidden without explicit casting string. @ least "type" // of array did not make false promises generic type // of list. string value = list.get(0); } // method receives array of lists. @ runtime generic type of // array gone. therefore, call method can called // anz list<sometype>[] array argument. void fill(list<?>[] array) { list<integer> list = new arraylist<integer>(); list.add(123) array[0] = list; }
in java, arrays of generic types not have generic representation. instead, arrays of type list[]
(in byte code type called [java.util.list
) share 1 single representation, list<string>
or list<integer>
or anyhing else. reasons of backwards compatibility , how arrays represented in java byte code. in other words, compiler has no way mark array instance accept example list<string>
objects. instead, compiler can mark array accept subtypes of list
in before java 5.
by stating
list<?>[] foo = new arraylist[3];
you tell compiler aware of compiler's inability check more list
s in array represented foo
of subtype of object
of course trivial. (with ?
being equivalent ? extends object
.) or in other words, when using wildcard ?
, ask compiler make sure list
contained in foo
of any generic type. stated before, because demand trivial, compiler can discharge demand , not produce warning.
now here comes catch:
class myclass<t extends number> { }
you still not state:
myclass<? extends number>[] foo = new myclass[3];
without compiler warning. why? not know. should type-safest declaration. makes less sence when seeing synonymous declaration
myclass<?>[] foo = new myclass[3];
is accepted. reason, asume compiler skips type checking of generic type variables when arrays involved entirely makes sure recognized impossibility of checking generic types of arrays assuring user typed <?>
compared legacy code lacks generic types.
Comments
Post a Comment