Yoda
Yoda

Reputation: 18068

Why the less matching overloaded method is called

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

Answers (4)

Kuldeep Jain
Kuldeep Jain

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

Shaunak
Shaunak

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

Kos
Kos

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

David Schwartz
David Schwartz

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

Related Questions