2013-04-02 6 views
5

Этот код:<? extends > Java синтаксис

List<? extends Reader> weirdList; 
weirdList.add(new BufferedReader(null)); 

имеет ошибку компиляции из

Метод добавления в список типа не применяется для (захват # 1-оф расширяет чтения?) arguments (BufferedReader)

Почему? BufferedReader расширяет читатель, так почему же это не «совпадение»?

+2

возможно дубликат [Java дженериков WildCard Вопрос: Список ] (http://stackoverflow.com/questions/5495383/java-generics-wildcard-question-list-extends-a) – yshavit

+0

(FWIW, что вы хотите здесь is 'List ', а не 'List '.) –

ответ

3

Для переменной вы дали:

List<? extends Reader> weirdList; 

Все следующие задания действительны:

weirdList = new ArrayList<Reader>(); 
weirdList = new ArrayList<FileReader>(); 
weirdList = new ArrayList<BufferedReader>(); 
weirdList = new ArrayList<InputStreamReader>(); 

Надеемся, что это объясняет свою ошибку компиляции. То, что вы пытаетесь, имеет смысл, если weirdList имеет значение типа ArrayList<BufferedReader>, но не имеет смысла для значения типа ArrayList<FileReader>. Поскольку переменная типа List<? extends Reader> может содержать значение любого типа (и более!), Java вызывает ошибку.

Дженерики на Java трудно найти. Вы можете придумать тип List<? extends Reader> как наиболее полезный для назначения или типов параметров в методах, чтобы они могли принимать самые разные типы. Для «регулярного использования» вам, вероятно, будет лучше «голый» общий, например List<Reader> или даже List<BufferedReader>.

6

Когда компилятор видит <? extends Reader>, то это предполагает, что это может быть любого типа, который или проходит Reader. Это может быть что-то, что несовместимо с BufferedReader, например StringReader. Поэтому, если общий тип определения класса отображается в параметре метода, такого как add, а тип экземпляра имеет что-то вроде <? extends Something>, компилятор должен запретить его по причинам безопасности типа. В этом примере это может быть List<StringReader>, поэтому вы не сможете добавить BufferedReader здесь.

6

List<? extends Reader> weirdList может содержать ссылку на любой тип List, который хранит любые типы Reader. Так что возможно, что

List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>(); 
List<? extends Reader> weirdList2 = new ArrayList<FileReader>(); 

Если Java позволит вам добавить BufferedReader к weirdList1 было бы также, чтобы позволить вам добавить BufferedReader к weirdList2 (ссылочный тип такой же), не предполагают, чтобы случиться так weirdList2 должен хранить только FileReader s.

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