Я прочитал книгу О'Рейли, в которой я узнал этот принцип получения результата .
- Используйте
extends
подстановочный знак, когда вы получаете значения только из структуры.- Используйте
super
подстановочный знак, когда вы помещаете только значения в структуру.- И не используйте подстановочный знак, когда вы оба хотите получить и поместить из / в структуру.
Исключения составляют:
Вы не можете поместить что-либо в тип, объявленный с
extends
подстановочным знаком, кроме значенияnull
, которое принадлежит каждому ссылочному типу.Вы не можете получить что-либо из типа, объявленного с
super
подстановочным знаком, за исключением значения типаObject
, который является супертипом каждого ссылочного типа.
Может ли кто-нибудь помочь мне глубже изучить это правило? Если возможно, расположите их иерархически.
Ответы:
Рассмотрим связку бананов. Это
Collection<? extends Fruit>
в том смысле, что это коллекция определенных видов фруктов, но вы не знаете (из этого объявления), какие фрукты это коллекция. Вы можете достать из него какой- нибудь предмет и знать, что это определенно будет фрукт, но вы не можете добавить к нему - возможно, вы пытаетесь добавить яблоко в связку бананов, что определенно будет неправильно. Вы можете добавитьnull
к нему, так как это будет допустимое значение для любого вида фруктов.Теперь рассмотрим вазу с фруктами. Это в том смысле
Collection<? super Banana>
, что это коллекция некоторого типа «больше чем»Banana
(например,Collection<Fruit>
илиCollection<TropicalFruit>
). Вы определенно можете добавить к этому банан, но если вы достанете предмет из миски, вы не знаете, что получите - это вполне может быть не банан. Все, что вы знаете наверняка, - это то, что это будет действительная (возможноnull
)Object
ссылка.(В общем, для вопросов по обобщениям Java можно найти ответы на часто задаваемые вопросы по обобщениям Java, которые содержат ответы практически на все вопросы, связанные с универсальными шаблонами, которые вы, вероятно, зададите.)
источник
Collection<? extends Fruit>
что- либо, кроме null, именно по этой причине, и вам придется явно приводить результат выборки элемента именно по этим причинам.Collection<? extends Person>
(или, что более вероятно, простоIterable<? extends Person>
, но ...). Код, создающий эту коллекцию, может нуждаться в том, чтобы он былCollection<Employee>
, а код потребления - нет.