Все об обобщенном программировании

max аватар
13

 

info picture В Java нельзя явно создать массив параметризированных коллекций

 

При попытке создать массив параметризованных коллекций

компилятор выдаст две ошибки. 

 

info picture В Java можно создавать не только обобщенные классы, но также и методы

 

В дополнение к обобщенному механизму для классов, джава позволяет параметризировать методы. В таком методе, угловые скобки ставятся после всех модификаторов метода, но перед возвращаемым типом:

Синтаксис для методов аналогичен синтаксису для обобщенных классов.

 

 

info picture Типизированные переменные не разрешены в catch-блоке, зато их можно использовать в throws

 

Интерфейс Executor спроектирован для выполнения секции кода и может бросать исключения, указанные в виде параметра. В примере показан код, который выполняет метод, что может бросить IOException. Конкретный тип исключения, IOException, указывается как параметр при создании реализации интерфейса Executor:

 

 

info picture Цикл for-loop может итерировать объекты, которые являются массивом или унаследованы от интерфейса java.lang.Iterable

 

Есть ли типы данных, которые не могут быть параметризированы?

Все типы, кроме перечислений (enums), анонимных вложенных классов и и классов исключений (exceptions) могут быть обобщенными. 

Анонимные вложенные классы. 

Они могут реализовать параметризованный интерфейс или унаследоваться от параметризованного класса, но они не могут сами быть обобщенными. Обобщенный анонимный класс - понятие бессмысленное. Анонимные классы не имеют имен, поэтому их объекты не могут быть созданы с передачей параметризированных аргументов. 

 Исключения (exceptions). Обобщенный класс не должен быть унаследован от класса Throwable ни напрямую, ни косвенно. Обобщенные исключения не поддерживаются по той простой причине, что механизм управления исключениями - это механизм времени выполнения, а виртуальная машина ничего не знает об обобщенных типах. 

Перечисления (Enums). Перечисления не могут иметь типизированных параметров. Концептуально, перечисление и его значения - статические. Поскольку типизированные параметры не могут быть использованы в статическом контексте, параметризация перечисления бессмыслена. 

 

Почему объекты обобщенных типов имеют один и тот же тип в рантайме?

Все из-за стирания типов. 

Компилятор транслирует обобщенные и параметризированные типы с использованием техники type erasure. Изначально, он собирает всю информацию о типах параметров и аргументов. Затем, например, List<String> транслируется в List, также именуемый raw type. То же самое происходит и с List<Long> и т.д. После трансляции, вся информация о типах параметров исчезает. В результате, все обобщенные объекты используют, на самом деле, один и тот же тип времени выполнения - List, который и записывается в байткод программы. 

Пример:

Результат:

 

Можно ли создать массив объектов параметризированного типа?

Нет, поскольку это небезопасно. 

Массивы ковариантны. Это значит, что массив ссылок супертипа является супертипом массива ссылок подтипа. Object[] - супертип String[], поэтому можно получить доступ к массиву строк через ссылочную переменную типа Object[]. 

Пример ковариантных массивов:

В дополнение ко всему, массивы несут за собой информацию времени выполнения о типах их компонентов. Такая информация используется во время выполнения в те моменты, когда необходимо удостовериться, что в массив не попали "битые" элементы другого типа. 

Проблема с созданием параметризированных массивов возникла потому, что стирается информация и типах данных и во время выполнения виртуальная машина ничего не знает о параметризированном типе. 


Конец
Джордж Бернард Шоу склоняется к тому, что единственный способ что-то узнать — это что-то делать.

как можно пользоваться совмещением методов в одном классе?? приведите пожалуйста пример!

Отправить комментарий

CAPTCHA
Чтобы оставить комментарий, введите пожалуйста код, изображенный на картинке
Image CAPTCHA
Введите символы, изображенные на картинке