(Apologies if it's been asked before, but my forum search yielded nothing and I really have to make sure)...
Using java 5 'generic types' : is it correct that 'type erasure' deletes *absolutely all traces* of the parametrized types, at runtime ? I.e, given: ArrayList<String> myList=new ArrayList<String>(); Is there absolutely no way for us to tell, at runtime, that "myList" is a list of <String>s ? (Of course, apart from extracting the first element and checking for its type... assume, for example, that the list is empty...).
All articles I've read indicate that that type is totally erased, but frankly I'm having difficulty believing that there was such a *huge* oversite in the specification... how difficult would it be to keep that information (in the instance level of course, since Class itself is shared) ?
Joined: Sep 24, 2003
No it is not completely lost - you can compile a simple example and observe for yourself in the bytecode. Alternatively, you can apply deductive reasoning. Consider a method that declares to return a type T<String>. You compile this method, and the attempt to invoke it. You call it and attempt to assign the return value to a T<Integer>. Of course, the compiler fails - it must know about the parameterised type - in this case, java.lang.String.
1. If I understand correctly, you're right that the compiler will introduce *casting* in the bytecode, but I didn't see it keep any flag that you can query in runtime... what I'm looking for is something like: - If I have: - Object list= new ArrayList<String>() Then I need to query 'list' in runtime, something like: "list.getParameterizedType()" that would return 'String'. BTW, I need it for writing general-purpose code, that could analyze any class - especially one loaded dynamically through Class.formName()...
2. The 'duductive reasoning' exercise seems interesting... you're right that the compiler does some validity checks on *compile time*, but I have a strong feeling that a lot of data is lost in *runtime* .
It's possible that every one of the articles you have read is incorrect. However if they were, and you could do what you wanted, I would expect that there would be new methods in the Reflection part of the API for that. And given that they would have to tell you the type involved in something likethey would be fairly complex and thus hard to miss.
Joined: Jan 30, 2000
Paul, sounds like you've got a bit more faith in Sun than I do. I could easily imagine that a method like that might be left out, even if it were both useful and possible. Sometimes they just miss things. Also I don't think such a method would be terribly complex-looking - it would probably look fairly similar to the existing getTypeParameters() method in Class. Most of the complexity is in the return object. You'd probably need to pass it a specific instance to evaluate though, to get the level of info the original poster seems to desire. If that were possible - which for the most part, it's not.
Sol Mam-Orn, here's more food for thought:
"I'm not back." - Bill Harding, Twister
Joined: Nov 13, 2002
LOL... thanks, Paul Clapham, for the hint
And thank you, Jim Yingst, for the 'food for thought'... I take the hint - all ArrayLists are of the same Class... but at least they could have left some indicator on the *instance* level, couldn't they ?
Thanks again !
Joined: Jan 30, 2000
Yes, in fact I'm pretty sure that they did retain that info somewhere in the instance, in one of the pre-release generics implementations Sun put out in the years before 1.5 was released. But for some reason they decided not to go that route in the final release. I believe they made some compromises for the sake of backwards compatibility. Too bad...