Странное поведение при перегрузке методов в Java - PullRequest
6 голосов
/ 01 июня 2010

Я столкнулся с этим странным (на мой взгляд) поведением сегодня. Пройдите этот простой тестовый класс:

public class Test {

public static void main(String[] args) {
    Test t = new Test();
    t.run();
}

private void run() {
    List<Object> list = new ArrayList<Object>();
    list.add(new Object());
    list.add(new Object());
    method(list);
}

public void method(Object o) {
    System.out.println("Object");
}

public void method(List<Object> o) {
    System.out.println("List of Objects");
}
}

Он ведет себя так, как вы ожидаете, печатая «Список объектов». Но если вы измените следующие три строки:

List<String> list = new ArrayList<String>();
list.add("");
list.add("");

вместо этого вы получите «Объект».

Я пробовал это несколькими другими способами и получил тот же результат. Это ошибка или это нормальное поведение? И если это нормально, может кто-нибудь объяснить, почему?

Спасибо.

Ответы [ 5 ]

12 голосов
/ 01 июня 2010

Это нормальное поведение. List<String> не является List<Object>, поэтому method(Object) является единственным применимым методом.

Если бы List<String> было List<Object>, вы могли бы нарушить безопасность типов, например, добавив Integer к List<String> (и его нельзя отловить во время выполнения из-за удаления типа) :

public void method(List<Object> o) { 
    o.add(new Integer(10));
}

Также обратите внимание, что у массивов другое поведение - String[] - это Object[], поскольку массив знает тип своего элемента и выдает исключение времени выполнения, если вы пытаетесь вставить в него неправильный объект.

6 голосов
/ 01 июня 2010

Это нормальное поведение, потому что когда вы определяете сигнатуру с помощью шаблонов, вы указываете один класс. (Если вы не используете подстановочные знаки , которых у вас нет, ссылка объясняет) ...

То есть List<String> не является List<Object>. Это, однако, List<? extends Object> - попробуйте и посмотрите.

1 голос
/ 01 июня 2010

Ну, это ожидаемо - список не имеет типа List<Object> Чтобы получить ожидаемые результаты:

public void method(List<?> o)

в качестве символа подстановки, он будет соответствовать вашему списку.

0 голосов
/ 01 июня 2010
0 голосов
/ 01 июня 2010

Как и ожидалось, поскольку List<String> не является List<Object>, как указано в другом ответе. Чтобы получить желаемое поведение, вам нужно использовать подстановочный знак:

public void method(List<? extends Object> o) { //or an unbounded wildcard List<?>
    System.out.println("List of Objects");
}

Смотрите также

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...