Java reflection get runtime type when using generics -
i wondering how can runtime type written programmer when using generics. example if have class main<t extends list<string>>
, programmer write
main<arraylist<string>> main = new main<>();
how can understand using reflection class extending list<string>
used?
i'm curious how can achieve that.
main.getclass().gettypeparameters()[0].getbounds[]
i can understand bounding class (not runtime class).
as comments above point out, due type erasure can't this. in comments, follow question was:
i know generics removed after compilation, wondering how classcastexception thrown runtime ? sorry, if stupid question, how knows throws exception if there isn't information classes.
the answer that, although type parameter erased type, still remains in bytecode.
essentially, compiler transforms this:
list<string> list = new arraylist<>(); list.add("foo"); string value = list.get(0);
into this:
list list = new arraylist(); list.add("foo"); string value = (string) list.get(0); // note cast!
this means type string
no longer associated type arraylist
in bytecode, still appears (in form of class cast instruction). if @ runtime type different you'll classcastexception
.
this explains why can away things this:
// next line should raise warning raw types // if compiled java 1.5 or newer list rawlist = new arraylist(); // since raw list, can hold object. // let's stick number in there. rawlist.add(new integer(42)); // unchecked conversion. not wrong, risky. list<string> stringlist = rawlist; // you'd think error. isn't! object value = stringlist.get(0);
and indeed if try it, you'll find can safely pull 42
value out object
, not have errors @ all. reason compiler doesn't insert cast string
here -- inserts cast object
(since left-hand side type object
) , cast integer
object
succeeds, should.
anyhow, bit of long-winded way of explaining type erasure doesn't erase all references given type, type parameter itself.
and in fact, now-deleted answer here mentioned, can exploit "vestigial" type information, through technique called gafter's gadget, can access using getactualtypearguments()
method on parameterizedtype
.
the way gadget works creating empty subclass of parameterized type, e.g. new typetoken<string>() {}
. since anonymous class here subclass of concrete type (there no type parameter t
here, it's been replaced real type, string
) methods on type have able return real type (in case string
). , using reflection can discover type: in case, getactualtypeparameters()[0]
return string.class
.
gafter's gadget can extended arbitrarily complex parameterized types, , used frameworks lot of work reflection , generics. example, google guice dependency injection framework has type called typeliteral
serves purpose.
Comments
Post a Comment