Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3. generics.pdf
Скачиваний:
10
Добавлен:
09.06.2015
Размер:
641.09 Кб
Скачать

Тонкости и особенности дженериков

©

NetCracker Technology Corp.

/

Сырые типы

.

Дженерики появились в Java . ( год). Но до этого уже было колоссальное количество кода на Java — без дженериков.

Для сохранения обратной совместимости есть возможность использовать обобщённые типы без указания типовых параметров:

List list = new List(); list.add(”abcd”); list.add( );

Обобщённые типы, употреблённые без параметров, называются сырыми

(raw).

Отличие от List<Object> и List<?> — в вариантности и безопасности:

List<String> strings = new ArrayList<>();

List<Object> objects = strings; // Ошибка компиляции

.

©

NetCracker Technology Corp.

/

Сырые типы

.

Дженерики появились в Java . ( год). Но до этого уже было колоссальное количество кода на Java — без дженериков.

Для сохранения обратной совместимости есть возможность использовать обобщённые типы без указания типовых параметров:

List list = new List(); list.add(”abcd”); list.add( );

Обобщённые типы, употреблённые без параметров, называются сырыми

(raw).

Отличие от List<Object> и List<?> — в вариантности и безопасности:

List<String>

strings

=

new ArrayList<>();

List<Object>

objects

=

strings; // Ошибка компиляции

List raw = strings;

// Всё ОК

.

©

NetCracker Technology Corp.

/

Сырые типы

.

Дженерики появились в Java . ( год). Но до этого уже было колоссальное количество кода на Java — без дженериков.

Для сохранения обратной совместимости есть возможность использовать обобщённые типы без указания типовых параметров:

List list = new List(); list.add(”abcd”); list.add( );

Обобщённые типы, употреблённые без параметров, называются сырыми

(raw).

Отличие от List<Object> и List<?> — в вариантности и безопасности:

List<String>

strings

=

new ArrayList<>();

List<Object>

objects

=

strings; // Ошибка компиляции

List raw = strings;

// Всё ОК

List<?> wildcard = string; // Тоже ОК, но...

.

© NetCracker Technology Corp. /

Сырые типы

.

Дженерики появились в Java . ( год). Но до этого уже было колоссальное количество кода на Java — без дженериков.

Для сохранения обратной совместимости есть возможность использовать обобщённые типы без указания типовых параметров:

List list = new List(); list.add(”abcd”); list.add( );

Обобщённые типы, употреблённые без параметров, называются сырыми

(raw).

Отличие от List<Object> и List<?> — в вариантности и безопасности:

List<String> strings

= new ArrayList<>();

List<Object> objects

= strings;

// Ошибка компиляции

List raw = strings;

// Всё ОК

 

List<?> wildcard = string; // Тоже ОК, но...

wildcard.add(”abcd”);

// ...ошибка компиляции

.

 

 

 

©

NetCracker Technology Corp.

/

Сырые типы

.

Сырые типы порождают предупреждения компилятора.

Вместо сырых типов всегда следует использовать либо wildcard’ы, либо параметр <Object>.

Единственное исключение — взаимодействие со старым унаследованным кодом. К сожалению, такое до сих пор встречается (а дженерикам уже скоро лет!).

.

©

NetCracker Technology Corp.

/

Внутреннее устройство дженериков

.

Дженерики существуют только на этапе компиляции.

Было:

public class TrivialComparator<T extends Comparable<T>> implements Comparator<T> {

@Override public int compare(T left, T right) { return left.compareTo(right);

}

}

public static <T> void add(Collection<? super T> coll, T elem) { ... }

Стало:

public class TrivialComparator implements Comparator {

@Override public int compare(Comparable left, Comparable right) { return left.compareTo(right);

}

}

public static void add(Collection coll, Object elem) { ... }

.

©

NetCracker Technology Corp.

/

Стирание типов

.

Процесс (и суть) удаления информации об обощённых типах называется

стиранием типов (type erasure).

Следствия стирания типов:

невозможно получить объект класса типа-параметра: T.class;

невозможно перегрузить метод только по типовому параметру:

public void <T> doSomething(List<T> list);

public void doSomething(List<String> list); // Ошибка компиляции

невозможно создать массив из элементов с типом-параметром:

public void <T> makeArray() {

return new T[ ]; // Ошибка компиляции

}

.

©

NetCracker Technology Corp.

/

Стирание типов

.

Есть хитрость, позволяющая сохранить информацию о типах-параметрах.

// Никакой информации нет

TypeTag<Optional<String>> tag = new TypeTag<Optional<String>>();

.

©

NetCracker Technology Corp.

/

Стирание типов

.

Есть хитрость, позволяющая сохранить информацию о типах-параметрах.

// Никакой информации нет

TypeTag<Optional<String>> tag = new TypeTag<Optional<String>>();

// А так есть!

TypeTag<Optional<String>> tag = new TypeTag<Optional<String>>() {};

Информация об обощённом типе в анонимном классе доступна через reflection.

.

©

NetCracker Technology Corp.

/

Что ещё осталось?

.

взаимодействие дженериков и массивов — более подробно;

подробности и правила стирания типов, bridge-методы;

подробности о наследовании, переопределении и перегрузке методов в обобщённых классах;

параметризованные конструкторы (о них вообще никто ничего не знает!);

дженерики и исключения;

подробнее про вывод типов;

захват wildcard’ов;

и т.д....

.

©

NetCracker Technology Corp.

/

Ссылки

.

Java Generics FAQ: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

Java Language Specification, . – . , . .

Oracle Java Generics Tutorial: http://docs.oracle.com/javase/tutorial/java/generics/index.html

.

©

NetCracker Technology Corp.

/