Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Дженерики (Часть 2); Версия 3.docx
Скачиваний:
4
Добавлен:
17.03.2016
Размер:
1.42 Mб
Скачать

Запреты при использовании дженериков

Я разделил запреты на 3 класса:

Класс Язык Java содержит в себе запреты, связаные со стандартными конструкциями Java. Эти запреты являются важными при объявлении объектов-дженериков.

Класс Методы содержит в себе запреты, которые важны при ООП. Важны, как ни странно!, при объявлении методов.

Класс Особые содержит в себе запреты, с которыми на практике редко сталкиваются, но всё равно они существуют, и могут потратить много вашего времени, если о них не помнить.

Теперь разберём детальней:

Нельзя передавать в качестве параметризованого типа примитивный тип.

Нельзя создавать любые контейнеры с примитивными типами: ArrayList<int>, Map<String, char>, Collection<double>. Вместо этого можно использовать ArrayList<Integer>, Map<String, Character>, Collection<Double>.

Это же касается методов. Если у нас есть класс Pair:

То параметризуемые типы обязательно должны быть не примитивными.

Невозможно создавать массивы из дженериков.

Итак всё понятно.

Нельзя использовать имя параметризованого типа, как конструктор этого типа.

В методе append1 описано создание экземпляра класса E через якобы констуктор E(). Это было бы весьма полезно, но логика языка Java позволяет создавать экземпляры параметризованого типа только так, как описано в методе append2.

P.S. throws Exception и конструкция try {} catch() {} используется из-за того, что метод newInstance() может выбросить ошибку. Детальнее об ошибках будет описано далее в курсе.

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

Рассмотрим статическое поле параметризированого типа в классе. Оно должно быть одинаково для всех екземпляров класса. Но екземпляры могут быть с разными типами (например,<Integer> или <String>). Но тогда и статическое поле должно быть своего типа для каждого екземпляра, что протеворечит цели статического поля. Аналогичные рассуждения для статического метода. И вот пример:

Удалив статическое поле и статический метод, можно добиться компиляции кода, не раньше.

Нельзя перегружать методы, где аргументы отличаются только параметризованым типом.

Это очень просто:

ТАК ДЕЛАТЬ НЕЛЬЗЯ!

Компилятор обижается ^). Тут нужно менять имя второй функции (или первой, LOL).

Нельзя использвоть instanceof с параметризованым типом и конкретным типом.

Для начала поймём, что такое instanceof.Это оператор, который проверяет на принадлежность объекта классу. Также если класс переменной наследует проверяемый класс, то возвращает true Если слева не объект абстрактного класса и объект не принадлежит проверяемому классу вылетает ошибка.

Теперь попытаемся проверить параметризованый тип на принадлежность разным класса:

Рассмотри первый метод. По комментарию уже видно, что он неправильный  Дело в том, что list может быть любого типа из (List<Integer>, List<Character>, List<String>…), и клмпилятор не может указать принадлежность.

Второй метод. Вот здесь другое дело: любой из возможных вариантов (List<Integer>, List<Character>, List<String>…) является подклассом List<?>. Также ArrayList<?> - является непараметризируемым, тот есть не подходит под условия запрета, что делает его возможным для применения.

Самое интересное: третий и четвёртый методы. А интересны они тем, что я не указал выбасывают они ошибку или нет. Поэтому: «Думайте сами, решайте сами...». Я серьёзно: попытайтесь отгадать.

Нельзя создавать, ловить и бросать объекты параметризированого типа.

А здесь непонятно, потому что тему исключительных ситуаций ещё не прошли. Но тот, кто знает и так поймёт, а кто не знает - не беспокойтесь: если не умеете создавать, ловить и бросать ошибки, то вы этого и не сделаете :).