Core-2: Jenerics Flashcards

1
Q

Коваринтность, Контрваринтность, Инваринтность

A

Вариантность — перенос наследования исходных типов на производные от них типы. Под производными типами понимаются контейнеры, делегаты, обобщения, а не типы, связанные отношениями “предок-потомок”. Различными видами вариантности являются ковариантность, контравариантность и инвариантность.

Ковариантность — перенос наследования исходных типов на производные от них типы в прямом порядке.
Контравариантность — перенос наследования исходных типов на производные от них типы в обратном порядке.
Инвариантность — ситуация, когда наследование исходных типов не переносится на производные.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Что такое Дженерики?

A

Дженерики (или обобщения) - это параметризованные типы.
Параметризованные типы позволяют объявлять классы, интерфейсы и методы, где тип данных, которыми они оперируют, указан в виде параметра.

Дженерики –cвойства языка, позволяющие типизировать классы и методы.
Типизировать - явно указывать типы объектов, с которыми может работать данный метод, класс или содержать данная структура данных.

  • Появились в версии 1.5
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Для чего нужны дженерики? (2)

A
  • Для строгой типизации и проверки на этапе компиляции:
    Дженерики позволяют передавать тип объекта компилятору в формате <тип>. Таким образом, компилятор может выполнить все необходимые действия по проверке типов во время компиляции, обеспечивая безопасность по стиранию и приведению типов во время выполнения:
    Информация о типах доступна только на этапе компиляции и стирается в runtime, и в байт код попадет только информация о том, что в программе есть некий список List list вместо List<String> list, например.</String>
  • Для универсификации кода: Используя дженерики, можно создать единственный метод или класс, который будет автоматически работать с разными типами данных.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Что такое сырые типы (raw type)?

A

“Сырые типы — это дженерик класс или интерфейс без спецификации типа :
~~~
List list = new ArrayList();
class User<T>{} => { User user = new User; }
~~~
они использовались до появления дженериков.
Не указывая их, под капотом используется Object</T>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Какие есть ограничения на использование Дженериков? (6)

A

1) работают только со ссылочными типами
2) Они инвариантны - наследование ограничено:
~~~
if (Foo extends Bar) ->
List<Foo> !extends List<Bar>
~~~
3) типизированный Т объект нельзя объявить через new: `Box<T> genericBox = new Box<T>();` - так нельзя
4) неприменимы к массивам, так как массивы ковариантны.
5) в обобщенном Т классе статические поля не могут быть static T, методы не могут возвращать Т. Зато стат. методы могут иметь параметры дженерики, причем этот метод необходимо дополнительно типизирвать (`public class C <T> { static <T> Object act( T е) { return new Object();}}`)
6) Типизированные классы не могут наследоваться от Throwable.</T></T></T></T></Bar></Foo>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Что означает конструкция public class Main <T extends Number> ?

A

Что класс работает с Number и наследниками, что дает возможность вызывать методы Number на T объекты. Такой возможности не было бы в случае class Main <T>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Что такое wildcard и какую проблему решает?

A

Языковая конструкция внутри даймонд-оператора.
Решает проблему наследования типов в дженериках. (коллекция <Интежер> не наследник коллекции <Намбер>)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Можем ли мы использовать ? для типизации параметра метода? (public static <?> void print(? item))

A

Нет, <?> может только параметризовать объекты, надо делать так:
public static <T> void print(T item)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Какое написание предпочтительнее:
public static <E> void swap(List<E> list, int src, int des); VS public static void swap(List<?> list, int src, int des);

A

2е, так как если мы имеем неограниченный дженирик тип ( если подойдет вообще любая коллекция) - то следует использовать <?>

Так же если дженерик присутствует в объявлении метода лишь однажды, нам следуеет выбрать вайлдкард, даже если имеется верхнее или нижнее ограничиние.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Можем ли мы обратиться к методу
public static <E> List<? extends Number> mergeWildcard(List<? extends E> listOne, List<? extends E> listTwo)
таким образом:
List<Number> numbersMerged = .mergeWildcard(numbers1, numbers2);
?

A

Он не скомпилируется, так как
List<Number> != List<? extends Number>, ведь метод имеет право вернуть любой конкретный лист (<Integer>, <Double>, ... ).
Если мы изменим возвращаемое значение на List<E>, то всё будет работать, так как теперь мы гарантируем, что у метода на входе и на выходе будут листы одного типа.

Таким образом, если метод возвращает дженеризированный объект, следует использовать типизированный дженерик, а не вайлдкард.

NB: Данный метод сработает если:
List list = ... ; / List<? extends Number> = ...; ,
и потом мы сможем попытаться извлечь из него Number:
~~~
Number n = (Number) numbersMergeds.get(0);
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Что означает тип List<? extends Number> в аргументе метода?

A

Что придет коллекция, содержащая Number или наследников.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Что означает тип List<? Super Integer> в аргументе метода?

A

Что придет коллекция, содержащая Integer или его предков.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Как понять List<?>?

A

List<?> == List<? extend Object>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

what is the difference between List<?> and List<T> in java?

A
  • ? означает вообще любой тип и при чтении из этого листа возвращается Object
    • из ? мы можем только читать, с Т можем делать всё.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

объяснить public User<?> getUser()

A

метод возвращает юзера с неизвестным параметром. может использоваться когда тип не важен или он будет определяться в рантайме (например при доставании юзера из базы).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Что такое PECS?

A

Produser Extends - Ковариантность
Из List<? extends Number> list мы можем читать только Number и его предков, но можем закастить в потомка:
~~~
Integer i = (Integer) list.get(0);
~~~
добавлять в <? extends Number>т не typesafe, так в один лист могут залететь и Integer & Double, ведь они оба <? extends Number>.
можем add(null);
_________________

Consumer Super: Контрвариантность
в List<? super Number> list мы можем писать только Number и его наследников, так как конструкция гарантирует что лист содержит только Number и выше.
Можем прочитать из него Object и закастить, так как в рантайме конструкция станет List<Object> list :
~~~
Integer n = (Integer) list.get(0);
~~~

Если мы хотим и писать и читать - wildcard использовать нельзя.

super применимо тольк к wildcard:
<T super Number> - ТАК НЕЛЬЗЯ.

17
Q

Почему нельзя объявить static T поле в Class<T> ?</T>

A

static поле - общее для всех объектов класса, а входящее Т будет разное для каждого конкретного объекта.

18
Q

Зачем параметризировать методы?

A

Если мы хотим расширить диапазон входных объектов, при условии, что функциональность и реализация должны быть общей для всех них

19
Q

Надо ли в параметризованном классе явно параметризовать метод?

A

Если плейсхолдер класса и метода совпадают, то не надо, но
1) если в методе появляется дополнительный П.Х. - его надо указать
2)если метод static, то параметр класса и метода будут взаимонезависимы, даже если одинаково называются :
~~~
public class Test<T> {</T>

public <V> T avs(T t, V v ) {
    return (T) v;
} public static <T> T method(List<? extends T> list) } ~~~
20
Q

Что происходит при type erasure в конструкции <T extends Number>?

A

Если в случае <T> JVM стирает тип до Object, то в случае T extends Number тип сотрется Number

21
Q

Как задать такой тип, который принимает только объекты наследующие N и имплементирующие 2 интерфейса?

A

<T extends N&Int1&Int2>

22
Q

как происходит стирание типов в JVM?

A
LIst<Integer> al = new ArrayList<>();
JVM: LIst al = new ArrayList();
int i = al.get(0);
JVM: int i = (Integer) al.get(0);
23
Q

Что означает тип List<? extends Number> в аргументе метода?

A

Что придет коллекция, содержащая Number или наследников.