Почему вызывается менее подходящий перегруженный метод - PullRequest
4 голосов
/ 15 марта 2012

Результат работы основного:

"Collection<?>".

Почему он не вызывает метод с параметром ArrayList<Integer>?

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);
}
}

Ответы [ 4 ]

5 голосов
/ 15 марта 2012

Поскольку l - это List, единственной функцией сопоставления является первая.Разрешение перегрузки выполняется во время компиляции, а не во время выполнения.Значение l не принимается во внимание, только его тип.

Что касается языка, это также может быть:

List l = foo();
test.method(1);

Это не таквсе равно, какое значение имеет l.

3 голосов
/ 15 марта 2012

overloadedMethod(ArrayList<Integer> o) не подходит, поскольку объявленный тип параметра l равен List, а не ArrayList, и перегрузка не выполняется в отношении динамических типов.

overloadedMethod(List<Number> o) не делает 'также не подходит, потому что аргументы универсального типа не совпадают.В Java нет ковариантных или контравариантных обобщений, таких как C #, поэтому List<Number> и List<Integer> не имеют отношения подтипа.

Следовательно, лучшая перегрузка overloadedMethod(Collection<?> o), поскольку два другихматч.

0 голосов
/ 15 марта 2012

Это будет соответствовать второму методу, т.е. overloadedMethod(List<Number> o), если вы измените Number на универсальный тип ?, например:

private void overloadedMethod(List<?> o) {
    System.out.println("List<?>");
}
0 голосов
/ 15 марта 2012

Это разрешение выполняется во время компиляции:

Тип l: List

, но его нельзя сопоставить с

List & ArrayList, поскольку 'T' не являетсято же самое, что конкретные 'Number' и 'Integer'

Может быть сопоставлено только с другим универсальным типом '?'и суперкласс 'Collection'

Таким образом, в этом случае разрешение определяется не структурой данных, а обобщениями.

...