Взгляните на следующий код:Java анонимным родовое наследство
ArrayList<? extends Object> list = new ArrayList<Object>();
list.add(new Object());
Это не компилируется. Вопрос в том, почему?
Взгляните на следующий код:Java анонимным родовое наследство
ArrayList<? extends Object> list = new ArrayList<Object>();
list.add(new Object());
Это не компилируется. Вопрос в том, почему?
ArrayList<? extends Object>
является такой же, как только
ArrayList<?>
и вы можете назначить любойArrayList
переменной этого типа. Например,
ArrayList<? extends Object> list = new ArrayList<String>();
является законным. Ясно, что семантика языка не позволит вам добавить Object
в такой список. Фактически, они не позволят вам добавить что-нибудь вообще, кроме null
, или что-то, что вы непосредственно извлекли из списка.
Как отметил Лукас в комментарии, далеко не тривиально даже добавить к нему собственный элемент списка: вам нужен вспомогательный метод для захвата подстановочного знака в именованный тип.
public static void main(String[] args) {
ArrayList<? extends Object> list = new ArrayList<String>();
addOwn(list);
}
static <T> void addOwn(List<T> l) { l.add(l.get(0)); }
Я думаю, причина в том, что Общие типы не являются полиморфными. Когда вы используете wildcards ?
с расширениями, вы не можете добавить что-либо в коллекцию, кроме null.
Вот пример того, что произойдет, если это разрешено:
Class Car{
}
class A extends Car {
}
class B extends Car{
}
Теперь у вас есть List<? extends Car>
public void someMethod(List<? extends Car> list){
list.add(new A()); //this is not valid
}
Также вы можете вызвать метод как это:
List<B> someList = new Array:list<B>();
somemethod(someList);
Проблема заключается в том, что Foo extends Object
не означает, что Collection<Foo>
может рассматриваться как подтип Collection<Object>
. Это просто потому, что прежний класс не позволяет вам делать все, что делает последний; например, вы не можете добавить Object
в Collection<Foo>
. Использование дженериков вместо какого-то конкретного класса Foo
не меняет этого.
* или что-то, что вы непосредственно извлекли из списка. *: Это меня удивит. Можете ли вы показать пример? :-) –
Я с Лукасом на этом. Пожалуйста, покажите пример. –
@ LukasEder Пример показан. –