параметризованной с wildcard коллекции в один момент можно присвоить одно, а в следующий - что-то иное, поэтому мы ищем общую "нижнюю" границу, удовлетворяющую всем возможным присвоениям
Идея в том, что мы отдельно копилируем класс Binary и подкладываем скомпилированый класс к предыдущей скомпилированной версии класса BinaryMain - у того в таблице методов нет метода, возвращающего String, а есть метод возвращающий Object.
@@ИгорьВойтович-р2к мб поздно уже, но возможно будет полезно читающим сейчас. Когда ты вызываешь метод изначально, у тебя в байткоде будет что-то такое: INVOKEVIRTUAL Binary get()Ljava/lang/Object; После рекомпиляции Binary дескриптор метода будет уже таким: get()Ljava/lang/String; Но BinaryMain так и оставит у себя в байткоде старый дескриптор (get()Ljava/lang/Object), по нему мы метод не найдем, так как мы поменяли возвращаемый тип в get. Касательно того, как это применимо к видео: Если бы мы сделали у Collections границу просто
Добавлю к ответу@@rustemgaliev3285 , что при компиляции BinaryMain сохраняет у себя дескриптор от Binary. Т.е. при изменении Binary надо перекомпилировать BinaryMain, чтобы он нужный дескриптор подхватил. В общем, данное усложнение с extends Object нужно только для поддержки всего старого кода и любой новый код так писать не надо.
Т.к. информация о типах стирается, компилятор ничего не знает о том какого типа объект нам вернет итератор коллекции list (String или наследника, upd: String или родителя). Соответственно он разрешает вернуть объект более общего типа, т.е. типа Object. Поэтому если заменить в foreach тип String на Object, то код скомпилируется, например: List
@@manOfPlanetEarth Спасибо за замечение, да, все верно "String или родителя". Касательно второго пункта, тоже верно, но даже если заменить super на extended, то никакой ошибки тут не будет, т.к. синтаксически такая конструкция будет абсолютно верна.
@@prianichnikov Максим, на самом деле я новичок и ни черта не понял кейс, который начали разбирать с 20:00. Вот вообще. Я уже 2 раза читал про дженерики и все равно не понимаю почему все эти присвоения нельзя делать. А понять хочу. У вас есть понимание этого момента?🤔 upd. упс. я перечитал ваш первый комментарий в этой ветке и кажись что-то стало проясняться... офигеть... не присвоения, а ДОБАВЛЕНИЯ!!!!...
массив листов стрингов нельзя создать? компилятор java не согласен с данным утверждением. public static void run(List ... data) { for (List x : data) for (String y : x) System.out.print(y + ", "); вполне принимает несколько списков со строками и выводит в консоль результат. если автор пытался вместо списка строк закинуть список чисел, то это уже не та история...
Почему-то докладчик называет "дженериком" параметр тип, который указывается в угловых скобках... Параметр тип - это НЕ дженерик!!! Дженерик - это тот первоначальный непараметризованный тип + параметр тип!!! Container - вся эта запись целиком является дженериком, но никак не взятый сам по себе...
Главная суть доклада: "Дженерики в джава это не логичное, кривое и убогое дерьмо, для использования которых тебе нужно заучить наизусть кучу правил их использования, понаписать себе шпаргалок, конспектов и в котором до конца можно разобраться только если у тебя в голове свежий компилятор джава и ты знаешь все "нюансы" и прочие "подводные камни" этой недотехнологии которую из-за обратной совместимости внедряли по принципу ломаного костыля".
Нелогичные - это точно. Я всё пытаюсь как-то понять, как они работают, а не просто заучить, и становится еще хуже. Лекция всё равно хорошая, спасибо.
параметризованной с wildcard коллекции в один момент можно присвоить одно, а в следующий - что-то иное, поэтому мы ищем общую "нижнюю" границу, удовлетворяющую всем возможным присвоениям
Отличный доклад. Можно ли все-таки пояснить последний момент со String'ом? К сожалению, обсуждение прервали на самом интересном месте.
Пойду учить питон
Скипай сразу эту объектную муть и переходи на го
@@wavka5126скипай это шнягу без ооп и возвращайся в java там виртуальные потоки завезли)
Молодец!
Может кто-то последний пример объяснить?
Не очень понятен момент, где Object o = new Binary().get();
Почему здесь Error? Разве String не запишется в Object?
Идея в том, что мы отдельно копилируем класс Binary и подкладываем скомпилированый класс к предыдущей скомпилированной версии класса BinaryMain - у того в таблице методов нет метода, возвращающего String, а есть метод возвращающий Object.
@@EkaterinaGrebtsova Ничего не понятно, но очень интересно. ©
@@ИгорьВойтович-р2к мб поздно уже, но возможно будет полезно читающим сейчас. Когда ты вызываешь метод изначально, у тебя в байткоде будет что-то такое:
INVOKEVIRTUAL Binary get()Ljava/lang/Object;
После рекомпиляции Binary дескриптор метода будет уже таким: get()Ljava/lang/String;
Но BinaryMain так и оставит у себя в байткоде старый дескриптор (get()Ljava/lang/Object), по нему мы метод не найдем, так как мы поменяли возвращаемый тип в get.
Касательно того, как это применимо к видео:
Если бы мы сделали у Collections границу просто
Добавлю к ответу@@rustemgaliev3285 , что при компиляции BinaryMain сохраняет у себя дескриптор от Binary. Т.е. при изменении Binary надо перекомпилировать BinaryMain, чтобы он нужный дескриптор подхватил.
В общем, данное усложнение с extends Object нужно только для поддержки всего старого кода и любой новый код так писать не надо.
List
Т.к. информация о типах стирается, компилятор ничего не знает о том какого типа объект нам вернет итератор коллекции list (String или наследника, upd: String или родителя). Соответственно он разрешает вернуть объект более общего типа, т.е. типа Object. Поэтому если заменить в foreach тип String на Object, то код скомпилируется, например:
List
@@prianichnikov
"String или наследника"
@@manOfPlanetEarth Спасибо за замечение, да, все верно "String или родителя".
Касательно второго пункта, тоже верно, но даже если заменить super на extended, то никакой ошибки тут не будет, т.к. синтаксически такая конструкция будет абсолютно верна.
@@prianichnikov
Максим, на самом деле я новичок и ни черта не понял кейс, который начали разбирать с 20:00. Вот вообще. Я уже 2 раза читал про дженерики и все равно не понимаю почему все эти присвоения нельзя делать. А понять хочу. У вас есть понимание этого момента?🤔
upd. упс. я перечитал ваш первый комментарий в этой ветке и кажись что-то стало проясняться... офигеть... не присвоения, а ДОБАВЛЕНИЯ!!!!...
Потому что List
кто-нибудь может объяснить первый вопрос, как мы можем сделать throw дженерика вместо exception?
public static void thr(Supplier src) throws E {
throw src.get();
}
це було гарно
массив листов стрингов нельзя создать?
компилятор java не согласен с данным утверждением.
public static void run(List ... data) {
for (List x : data)
for (String y : x)
System.out.print(y + ", ");
вполне принимает несколько списков со строками и выводит в консоль результат.
если автор пытался вместо списка строк закинуть список чисел, то это уже не та история...
👍за доклад!👎за то, что обрезали объяснение последнего примера.
Какого хрена ведущий не дал последний пример обсудить?
Почему-то докладчик называет "дженериком" параметр тип, который указывается в угловых скобках... Параметр тип - это НЕ дженерик!!! Дженерик - это тот первоначальный непараметризованный тип + параметр тип!!! Container - вся эта запись целиком является дженериком, но никак не взятый сам по себе...
1:09 чупакабра
Главная суть доклада: "Дженерики в джава это не логичное, кривое и убогое дерьмо, для использования которых тебе нужно заучить наизусть кучу правил их использования, понаписать себе шпаргалок, конспектов и в котором до конца можно разобраться только если у тебя в голове свежий компилятор джава и ты знаешь все "нюансы" и прочие "подводные камни" этой недотехнологии которую из-за обратной совместимости внедряли по принципу ломаного костыля".
Ага) Строгая типизация? Не, не слышали!)
Невероятно бесполезный доклад, если вы ещё не владеете дженериками как докладчик.
ну вообще доклады для разного уровня разработчиков существуют.
можно посмотреть что-то другое.