2012-03-15 3 views
4

Результат выполнения основной является:Почему менее соответствующий перегруженный метод называется

"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); 
} 
} 
+0

Я считаю, что он также должен быть 'метод (ArrayList л)' – Kos

ответ

0

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

private void overloadedMethod(List<?> o) { 
    System.out.println("List<?>"); 
} 
5

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

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

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

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

+0

см комментарии ниже мой пост; это еще не все, не работает, даже когда мы меняем 'l' на' ArrayList ', чтобы типы выглядели точно такими же. – Kos

+0

@Kos: вопрос был изменен, и мой ответ относится к более ранней версии вопроса. –

3

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

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

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

+0

По ошибке я изменил код. Должен быть ArrayList l = новый ArrayList (); и результат был тот же. – Yoda

+0

Ммм вы правы, это _is_ подозрительно :), пожалуйста, отредактируйте свой вопрос, чтобы отразить эту проблему, чтобы более умные люди, чем я, заметят, какова настоящая проблема: – Kos

+0

Для справки: http://ideone.com/KUobo – Kos

0

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

тип л Список

, но она не может быть согласован с

Список & ArrayList, потому что «Т» не совпадает с конкретным «Номер 'и' Integer '

Он может быть сопоставлен только с другим общим типом'? ' и суперкласса «Коллекция»

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

Смежные вопросы