
Lev
03.09.2017
17:55:43
Vic, если я не понимаю что за инвариантность и ковариантность - бессмысленно объяснять эти термины этими же терминами.
Окей, в яве лист мутабельный.
List<Object> может принимать и отдавать ваще любой объект
List<String> может принимать и отдавать String и всех его наследников
И чего?

Anton
03.09.2017
17:56:06
у стринга нет наследников он файнал

Lev
03.09.2017
17:56:32
Ну пусть будут, для примера.

Anton
03.09.2017
17:56:59
у тебя вопрос что такое ковариантность и инвариантность?

Google

Lev
03.09.2017
17:57:02
Что такого что они мутабельны? Где может быть ошибка?

Vic
03.09.2017
17:57:29
простой пример. если я написал метод, который умеет обрабатывать лист животных (получать их них котлеты), то если я в него передам лист коров - в котлине и скале это будет валидно.
то есть наследование между коровой <: животным транслируется и на листы коров и животных (т.к. лист - иммютабл и соот. ковариантен)

Anton
03.09.2017
17:58:00
String[] strings = new String[5];
Object[] objects = strings;
objects[0] = 12;
смотри
что будет?

Boris
03.09.2017
18:00:17
List объявлен как <out T>, что позволяет работать с элементами наследниками T

Lev
03.09.2017
18:02:39

Anton
03.09.2017
18:02:50
подтолкни

Lev
03.09.2017
18:03:21
я понимаю что последняя строка попробует добавить инт в список из строк (и наверно это должно быть приведет к ошибке или при вставке)
А ява наверно запрещает вторую строку, чтобы ничего не навернулось

Anton
03.09.2017
18:03:47
всмысле
это же на джаве код)

Google

Anton
03.09.2017
18:04:09
массивы ковариантнты поэтому этот код скомпилится а потом вылетит arraystoreexception
дженерики инвариантны поэтому будет компайл еррор
List<String> strings = new ArrayList();
List<Object> objects = strings; // ошибка компиляции

Quantum Harmonizer
03.09.2017
18:09:56
Попробую объяснить :)
#generics #дженерики #вариативность #variance #инвариантность
MutableList<CharSequence> гарантирует, что всё, что из него достаёшь, — CharSequence. В него можно положить любую CharSequece. Нельзя просто так взять и рассматривать его как MutableList<String>, потому что там может оказаться, например, StringBuilder. Такое поведение — инвариантность.
Нельзя и рассматривать MutableList<String> как MutableList<CharSequence>, потому что в первый разрешено класть только String.
Это инвариантность: MutableList<String> и MutableList<CharSequence> — разные типы.

Lev
03.09.2017
18:11:33
эти типы как то в обратную сторону работают

Anton
03.09.2017
18:11:53

Lev
03.09.2017
18:11:57
String[] strings = new String[5];
Object[] objects = strings;
objects[0] = 12;
потому что Object[] просто "сужает" мои возможности по работе с элементами массива (но внутри те же строки)
и вроде как добавление инта в массив объектов тоже валидно, но на самом деле это ведь не массив объектов, а массив строк, и инт их наследником не является... тут ... вот не входит никак

Quantum Harmonizer
03.09.2017
18:12:16
#generics #дженерики #вариативность #variance #ковариантность
В List<CharSequence> нельзя ничего положить, можно только достать. Поэтому List<String> можно рассматривать как подтип листа чарСиквенсов — ведь любая строка является CharSequence'ом и такое присваивание ничего не поломает.
Это ковариантность.

Anton
03.09.2017
18:12:51
можете прочитать главну effective java про то что коллекции лучше массивов. там как раз про ковариантность рассказывается

Quantum Harmonizer
03.09.2017
18:13:38
Есть ещё контравариантность, но это встречается довольно редко)

Lev
03.09.2017
18:18:18
Но вот Object[] objects = strings - это вот... не к массиву относится, а к его элементам
ща

Anton
03.09.2017
18:19:18
почему неа
String[] strings = new String[5];
strings[0] = 12; не получится
Object[] objects = strings;
objects[0] = 12; получится

Lev
03.09.2017
18:19:45
Ща, я придумаю пример и напишу... я просто аналог никак найти не могу

Anton
03.09.2017
18:19:50
давай)

Lev
03.09.2017
18:25:43
ну вот... с натягом конечно, но надеюсь понятен смысл будет.
String[] strings = new String[5]; //у меня есть удлинитель с ЕВРО розетками. Массив для ЕВРО розеток
Object[] objects = strings; //здесь я говорю, что это в приципе.. ПРОСТО розетки. Но это относится только к самим розеткам, а не к массиву. То есть каждую ЕВРО розетку я могу рассматривать как ПРОСТО розетку. Но сам удлинитель - все равно ЕВРО розеточный.
objects[0] = 12; а тут я хочу туда воткнуть СОВЕТСКУЮ вилку, на основании того я ранее ошибочно предположил что это массив ПРОСТО розеток. Но на самом деле здесь надо думать что я втыкаю СОВЕТСКУЮ вилку в ЕВРО розетку.

Google

Lev
03.09.2017
18:26:23
тоже херь какая то
String[] strings = new String[5];
strings[0] = 12;
Object[] objects = strings;
objects[0] = 12; - а достать то получится?

Anton
03.09.2017
18:30:25
ну да вроде так)
objects[0] = 12; - а достать то получится?
доставать не придется тк ошибка будешь раньше и она звучит как arrayStoreException тоесть проблем даже до стадии доставания

Lev
03.09.2017
18:31:56
не, все равно не входит...
Есть у меня машина по деланию котлет из коров
Я прав когда говорю что в принмипе она далет котлеты из животных. И раз из животных то почему бы туда не сунуть кита...

Anton
03.09.2017
18:33:55
ну как не входит. ковариантность значит что в качестве типа можно использовать класс и его наследники. инвариантность значит что только сам класс
какие еще котлеты)

Lev
03.09.2017
18:34:26
да та же проблема с котлетами

Ivan
03.09.2017
18:34:47
Написано же

Anton
03.09.2017
18:35:03
ну вот ковариатность можно использовать котлеты куриные говяжьи и свинные, а инвариантость только котлеты без уточнения
ужасно)

Anton
03.09.2017
18:35:40

Anton
03.09.2017
18:36:15
что запуталось. массивы ковариантнты в джаве а коллекшн апи нет

Lev
03.09.2017
18:37:10
Не, помоему проблема у меня в голове, надеюсь не в ДНК.
1. Ксть машина которая делает котлеты из КОРОВ
2. Я могу сказать что эта машина принимает на вход ЖИВОТНЫХ
3. КИТЫ - ЖИВОТНЫЕ, почему я не могу запихать туда КИТОВ?
... где блин ошибка? =)
Я не пьян, я адекватен, но именно тут у меня недопонимание.

Anton
03.09.2017
18:37:26

Lev
03.09.2017
18:37:55
что то то с П2 не ладно
.... все коровы - животные, киты - тоже животные, но это не значит что киты это коровы (или наоборот)

Anton
03.09.2017
18:39:13
ну вот это явление и называется инвариантность. потому что не важно корова у тебя или кит там дженерик тайп стоит - животные. пихаешь туда только животных.
ковариантность - это значит можешь пихать и китов и коров и просто абстрактных животных

Google

Anton
03.09.2017
18:40:45
https://stackoverflow.com/questions/18666710/why-are-arrays-covariant-but-generics-are-invariant

Aleksandr
03.09.2017
18:40:57

Lev
03.09.2017
18:41:25
и коровы не предки китов

Anton
03.09.2017
18:42:33
вот вайлдкарды получается ковариантны

Lev
03.09.2017
18:45:13
String[] strings = new String[5];
Object[] objects = strings; - вот эта операция мутит воду, тут я говорю что массив КОРОВ это массив ЖИВОТНЫХ, и я могу обращаться с ними как с животными, но добавить в массив КИТОВ я не могу..... зараза ну что не так то...
objects[0] = 12;

Ivan
03.09.2017
18:45:59
Может сосцы эррэя посмотреть сначала

Lev
03.09.2017
18:46:17
Ого ты опечатался

Anton
03.09.2017
18:46:35
лол
ну хз я немогу доступнее обьяснить сорри) почитай еффектив джаву вот ту главу или пост на стаке выше

Lev
03.09.2017
18:46:57
дело не в java)
... отойду, пойду потру сосцы эррея

Ivan
03.09.2017
18:47:32

Anton
03.09.2017
18:47:34
и ивану потри

Quantum Harmonizer
03.09.2017
18:48:29

Lev
03.09.2017
18:48:32
ну если после этого у меня войдет...

Vladimir
03.09.2017
18:54:19

Lev
03.09.2017
18:54:41
говорю же не к яве это относится
Object[] objects = strings; - когда я так делаю, я получаю объект, который не то же самое что новый Object[]. Подобное приведение типа позволяет мне лишь по другому "посмотреть" на String[]
То есть на самом деле я получаю не настоящий Object[]

Anton
03.09.2017
18:55:41
а где написано что это новый обьект Object[]

Google

Lev
03.09.2017
18:55:50
Это не то же самое что
Object obj = string

Anton
03.09.2017
18:56:16
почему) массив такой же обьект
я присвоил ему значение - ссылку на массив стрингс
и стрингс и обджектс ссылаются на один обьект в хипе
понятное дело что это не новый обьект Object[]
если я где то соврал поправьте плз

Lev
03.09.2017
18:58:59
Он будет вести себя не так же как Object[], методы у него другие, они так и принимают String

Anton
03.09.2017
19:00:15
у всех массивов одинаковые методы)

Lev
03.09.2017
19:03:35
Object obj = string; //String
Object[] objects = strings; // String[]
вот почему от первого больно не будет а от второго будет?
потому что.... слово перед [] не относится к типу переменной
то есть... в первой строке Object и String относятся к типам переменных которые слева и справа от =
а во второй строке Object и String - они про типа внутри объектов, про типы в том числе в методах
Это вот железно справедливо? :
применительно к типу переменной я могу двигаться от частного к общему
применительно к аргументу в методе - наоборот

Anton
03.09.2017
19:07:42
ты можешь двигатся и от общего к частному если уверен что это наследник)
тайпкаст

Lev
03.09.2017
19:10:03
Если да, то значит String[] означает (я это знаю, вы не подумайте) что я определаю тип внутри класса в свойствах и методах. Я могу спокойно кастовать "представлять" все свойства как Object, но не могу этого же сделать в методах.

Anton
03.09.2017
19:18:17
сорри пока не могу продолжать)

Lev
03.09.2017
19:21:17
короче... в определенных случаях я могу двигаться от наследника к предку, а в других - наоборот
при присваивании типа Object obj = string я могу двигаться от наследника к предку.
то же при возврате значения из метода (то же самое грубо говоря)
А вот в аргументе метода - "менять" можно только наоборот.
Потому что это разные вещи %) В одном случае (каст переменных) все коровы - животные, в другом (аргумент) все буренки - коровы, я могу сунуть буренку в метод принимающий коров.
А вот вот эта вот хрень - Machine<T> - вот это вот T оно определяет НЕСКОЛЬКО вещей сразу. И тип переменных/возврата методов в объекте и тип аргументов.
Вот тут вот и жопка вероятно была у меня.
соответственно когда я делаю Object[] objs = strings; - то я (типа как поменяв тип) на самом деле могу безопасно использовать все, кроме передачи аргументов

Anton
03.09.2017
19:24:04
что например)

Lev
03.09.2017
19:24:18
ну получать объекты я могу спокойно
get(1)