I have a big confusion and I am sure you guys could help me out....
Now after type erasure
Now, for this above code, the output is overloadedMethod (Collection<?>).
I have two doubts:
1: why is the output as above as after type erasure, List<T> would be same as List.In that case List overloaded version should be called.
2:When really does type erasure occurs?When does it get in picture?Does it happens when the compiler has compiled one generic statement , means on line by line basis?
Need to clarify these two doubts.
Code has been taken from URL
Please help me out.
One might mistakenly believe that the compiler would decide that the List version of the overloaded method is the best match. But that would be wrong, of course. The List version of the overloaded method was originally a version that takes a List<Number> as an argument, but on invocation a List<T> is passed, where T can be any type and need not be a Number . Since T can be any type the only viable version of the overloaded method is the version for Collection<?> .
But I obviously went through this explaination.
What I was asking was when do we know that the tyoe erasure would come into picture?Does type erasure is done by the compiler as soon as it comes across a generic code, or the compiler first validates the while code and then erases the type?
As you might be aware , during class loading, there are 3 steps
Step 1. Loading
Step 2. Linking
My guess is that type erasure happens at Step 2 -(Linking). So for any type erasure activity, first of all, Java class should have a valid Java code (syntax wise) in it.
But I am not sure .. waiting for someone to reply with correct and firm answer.
Abhay Agarwal wrote:But I am not sure .. waiting for someone to reply with correct and firm answer.
Does it really matter? The fact is that generics is a compile-time mechanism. To all intents and purposes, it doesn't exist at runtime.
It's also not a 100% solution - in particular, you can't create generic arrays without outside help (you can define and reference them though) - but for the other 95% it's darn good.
I tried to think about it a bit.
I need to confirm below points as per my understanding...
1.Compiler uses type inference to decide which method to invoke as per overloading.So here in this example, the method invocation is decided by the type inference.
2.Type erasure comes into picture when the code passes the type-inference check, i.e the code is correct after the type-inference.After type inference, if all the matching seems correct then the compiler would perform type erasure and generate byte code.
Abhay Agarwal wrote:My guess is that type erasure happens at Step 2 -(Linking).
No, type erasure happens during compilation, which is ofcourse before runtime - before class loading, linking and initialization.
Sudhanshu Mishra wrote:What I was asking was when do we know that the tyoe erasure would come into picture?Does type erasure is done by the compiler as soon as it comes across a generic code, or the compiler first validates the while code and then erases the type?
The compiler will not erase the generics immediately; if the compiler would effectively ignore the generics, there would be no point in using generics at all. The compiler uses generics for type checking, but purely for type checking that can be done at compile time. When the type checks pass, then the compiler erases the generics.
Which overloaded version of a method is called, is determined at compile time, before the generics are erased. That's exactly why you see in your example that overloadedMethod(Collection o) is called. The version that takes a List<Number> does not match, because an ArrayList<Integer> is not a List<Number> (*). So, in that case, the generics are taken into account to check which method should be called.
(*) If you would change the method to take a List<? extends Number>, it would call the List version.