Передача списка <Subclass>методу, ожидающему List <SuperClass> - PullRequest
8 голосов
/ 17 февраля 2012

У меня есть метод, который ожидает List<SuperClass> в качестве аргумента:

public void myMethod(List<SuperClass> list) {}

Я хочу вызвать этот метод с List<Subclass> что-то вроде:

List<SubClass> subList = new ArrayList<>();
// ...
myMethod(subList); // Got an argument mismatch error on this line.

Shouldnя смогу сделать это, когда SubClass extends SuperClass?

Ответы [ 2 ]

20 голосов
/ 17 февраля 2012

Нет, дженерики так не работают.Что вы можете сделать, это определить свой метод как MyMethod(List<? extends SuperClass> list) (условно он должен называться myMethod(...) btw).

Проблема с List<SuperClass> против List<SubClass> заключается в том, что вы можете добавлять новые элементы втакие списки, тогда как компилятор не позволил бы вам добавить что-либо к List<? extends SuperClass> - и на это есть причина:

Рассмотрим следующее:

class A {}

class B extends A {}

class C extends A {}

Если у вас теперь есть List<A> Вы можете добавить экземпляры A, B и C.Однако, если вы передадите List<B> методу в качестве параметра List<? extends A>, компилятор не будет знать, разрешено ли добавлять экземпляры A или C в этот список (это не будет разрешено, но в случае, если вы передадите List<A>, это будет).Таким образом, компилятор не позволяет вам этого делать.

Определение параметра как List<A> говорит компилятору, что можно помещать экземпляры всех трех классов в этот список.Теперь, если вам будет разрешено передать List<B> в качестве такого параметра, вы можете получить List<B>, который содержит экземпляры A и / или C.И это явно не то, что вы хотите, и может привести к ошибкам во время выполнения, которые должны быть предотвращены уже во время компиляции - с помощью обобщений.Вот почему ваш подход не работает.

0 голосов
/ 11 июня 2016

Стоит отметить, что вы также можете создать список вашего суперкласса из списка подклассов как таковой:

myMethod(new ArrayList<SuperClass>(list));
...