Комментарии 13
Я так и не понял, почему они не сделали как в С#, в котором нет type erasure. Я вроде как бы верю, что там были какие-то проблемы с обратной совместимостью, но вот почему там нужна была эта совместимость сама по себе? Почему нельзя было просто дженерики рассматривать как самостоятельный поднабор типов?
хороший вопрос ,не знаю почему задизлайкали , я честно с C# по работе редко встречался , но заметил такую вещь , там есть коллекции с generics и коллекции с примитивами , думаю это было сделано потому что изначально generics не было и архитекторы решили написать новый фрэимворк коллекций с generics и поддерживать старый
Может из-за этого oracle отказались от идея потому что поддерживать две апишки слишком дорого , легче добавить generics в существующие колекции и добавить type erasure чтобы старый код не ломался при переходе на новые версии . Еще есть Project Valhalla , одна из идей переделать Generics чтобы List<Integer> работал с примитивами вместо врапер классов
Потому что С# писался после java и они знали на какие грабли лучше не наступать дважды, а core в java от версии к версии не переписывается, а дописывается.
Т.к. я не копенгаген в Java, хочу заметить, что статья немного неполна без описания, как именно объявлены методы get() и add() в листе. Как компилятор вообще понимает, что get - это чтение, а add - это запись? Для него же метод методу рознь. Там какой-то синтаксис для этого?
Понимает по тому, в каком месте стоит определение типа. Если в аргументе - запись, если в возвращаемом значении - чтение. Это не более чем условность для программистов, познающих generic'и. Не самая удачная, на мой взгляд.
И еще, какая у этого всего связь с терминами ковариантность/контравариантность? Похожие вроде вещи. Или это одно и то же? Или одно - подтема другого?
Но если есть те, для кого принцип PECS остаётся туманным и непонятным, а упорное гугленье только сгущает «туман»
Как-то странно вы гуглили, вот замечательные видео, где все великолепно объяснено:
youtu.be/_0c9Fd9FacU
youtu.be/MniNZsyjH9E
public static void someMethod (List<? extends Class3> list) {
Class4 class4 = list.get(0);
}
"Отсюда неочевидный вывод:" как раз таки очевидный
Допустим Producer Extend работает таким образом и мы можем получить Class4 который наследует Class3. Для примера
public class Class3{
void test(){}
}
public class Class4 extends Class3{
void test2(){}
}
Если мы из листа получили Class4 а в листе изначально был Class3 , у Class3 нету метода test2 , у него есть метод test() и все методы его родителей поэтому extends Class3 может только получить родителя так как компилятор уверен что методы Class3 и всех его родителей будут у объекта который мы получаем
public static <T extends Comparable<? super T>> T max(List<T> list)
а не так:
public static <T extends Comparable<T>> T max(List<T> list)
И, желательно, указать автора этого мнемонического правила
Подробно о PECS