Reputation: 18068
The result of running the main is:
"Collection<?>".
Why is it not calling the method with ArrayList<Integer>
parameter?
import java.util.*;
public final class GenericClass<T> {
private void overloadedMethod(Collection<?> o) {
System.out.println("Collection<?>");
}
private void overloadedMethod(List<Number> o) {
System.out.println("List<Number>");
}
private void overloadedMethod(ArrayList<Integer> o) {
System.out.println("ArrayList<Integer>");
}
public void method(List<T> l) {
overloadedMethod(l);
}
public static void main(String[] args) {
GenericClass<Integer> test = new GenericClass<Integer>();
ArrayList l = new ArrayList<Integer>();
test.method(l);
}
}
Upvotes: 4
Views: 648
Reputation: 8598
It will match with second method i.e. overloadedMethod(List<Number> o)
if you change Number
to generic type ?
like following:
private void overloadedMethod(List<?> o) {
System.out.println("List<?>");
}
Upvotes: 0
Reputation: 18028
This resolution is performed at Compile time:
The type of l is List
but it cannot be matched to
List & ArrayList because 'T' is not same as specific 'Number' and 'Integer'
It can only be matched to another generic type '?' and a super class 'Collection'
So in this case resolution is not decided by Data structure but by generics.
Upvotes: 0
Reputation: 72299
overloadedMethod(ArrayList<Integer> o)
doesn't fit because the declared type of parameter l
is List
not ArrayList
and overloading isn't done with respect to dynamic types.
overloadedMethod(List<Number> o)
doesn't fit as well because the generic type arguments don't match. Java doesn't have covariant or contravariant generics like C#, so List<Number>
and List<Integer>
don't exhibit a subtype relation.
The best overload is hence overloadedMethod(Collection<?> o)
, since the other two don't match.
Upvotes: 3
Reputation: 182827
Since l
is a List
, the only matching function is the first one. Overload resolution is done at compile time, not run time. The value of l
isn't taken into account, only its type.
As far as the language is concerned, this might as well be:
List l = foo();
test.method(1);
It doesn't care what value l
has.
Upvotes: 5