Эти вещи известны, в теории типа, так как дисперсии с <? extends T>
быть одним из вариантов обозначения, и <? super T>
быть противопоказаны вариант обозначения. Самое простое объяснение состоит в том, что ?
может быть заменен любым типом, продолжающимся T
в ко-вариантной нотации, а ?
может быть заменен любым типом, который T
распространяется в противоположном варианте.
Использование co и contra-variance намного сложнее, чем может показаться на первый взгляд, особенно потому, что дисперсия «переключается» в зависимости от положения.
Простым примером может служить функциональный класс. Скажем, у вас есть функция, которая принимает A
и возвращает B
. Правильная нотация для нее заключалась бы в том, что A
является контравариантным и B
os co-variant.Чтобы лучше понять, как это так, давайте рассмотрим метод - давайте назовем его g
- который получает эту гипотетическую функция класс, где е предполагается получать Arc2D
и вернуть Shape
.
Внутри g
, это f
называется пропусканием Arc2D
и возвращаемое значение используется для инициализации Area
(который ожидает получить Shape
).
Теперь, предположим, что вы пройдете Shape
и получите Rectangle2D
. Так как Arc2D
является также Shape
, то g
не получит сообщение об ошибке пропускании Arc2D
к f
, а поскольку Rectangle2D
также Shape
, то он может быть передан в конструктор Area
«s.
Если вы попытаетесь инвертировать любые отклонения или заменить ожидаемые и фактические типы в этом примере, вы увидите, что это не сработало. У меня нет времени прямо сейчас, чтобы записать этот код, и моя Java во всяком случае очень ржавая, но я увижу, что я могу сделать позже, - если никто не будет достаточно любезен, чтобы сделать это первым.
Эффективная Java отличная, но у меня все еще нет второго издания (( – Roman
@Roman вы можете скачать главу о Generics из ссылки, которую я добавил :-) –
Спасибо, я прочитаю. знаете, есть ли какие-либо другие «главы примеров» бесплатно? – Roman