Generic Wildcard Capture conversion Covariance Invariance Contravariance
От: Aleksei_Lekomtsev  
Дата: 19.10.23 13:45
Оценка:
class A {}
class B extends A {}
class C extends B {}

List<? extends B> list1 =
List<? super B> list2 =
List<B> list3 =


// чем отличаются list1, list2, list3 ?
// что можно положить в list1, list2, list3 ?
// что можно достать из list1, list2, list3 ?


В list3 можно присвоить(через =) только list<B>(инвариант)
В list2 можно присвоить(через =) только list<B> и list предков B, т.е. List<A>, List<Object>(ковариант)
В list1 можно присвоить(через =) только list<B> и list наследников B, т.е. List<C>(контрвариант)

Дальше сложнее,
в list1 через add ничего нельза добавить(Почему?)
В list2 через add можно добавить B и наследники B, т.е. С. Я так понимаю здесь работает capture conversion? Т.е. List<? super B> конвертируется в List<Object> или в List<B>,
поэтому можно добавлять B и его наследников, так как эти объектами будут как Object так и B?
В list3 через add можно добавить B и наследники B, т.е. С. Т.е. здесь тоже самое что и с List<? super B>? Или есть разница, что и когда выбирать?

в list1 через get можно читать B и A(Почему не C?)
В list2 через get можно читать Object?(Почему только Object)
В list3 через get можно читать B и A(В чем разница с List<? extends B>?)

Можно какие-то практические примеры когда какие типы более appropriate/fit?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.