n Использовать примитивные типы в качестве параметров-типов нельзя
n Если одинаковые настраиваемые типы имеют различные аргументы, то это различные типы
n Обеспечивается более жесткий контроль типов на стадии компиляции
Общий синтаксис
n Объявление настраиваемого типа
class имяКласса<список-формальных-параметров> {...}
class Generic2<T, E> {...}
n Создание ссылки и объекта настраиваемого типа
имяКласса<список-фактических-параметров> имяПеременной = new имяКласса<список-фактических-параметров>(список-аргументов);
Generic2<Integer, String> gObj = new
Generic2<Integer, String>(10, "ok");
Вопрос 63 Настраиваемые типы с ограничениями. Метасимвольный аргумент. Настраиваемые методы. 20-22 Лекция Collections Framework
Ограниченные типы
class Stats<T extends Number> {
T[] nums;
Stats(T[] o) {nums = o;}
double average() {
double sum = 0.0;
for(int i = 0; i < nums.length; i++)
sum += nums[i].doubleValue();
return sum / nums.length;
}
}
n Ограничение типа позволяет использовать у ссылок методы и поля, доступные в типе-ограничителе
n Типы, не наследующие от указанного, не могут быть использованы при создании объектов
n Как имя типа может быть указан интерфейс!!!
n Как имя типа может быть указан ранее введенный параметр!!!
class Generic3<T extends Comparable<T>> {...}
Метасимвольный аргумент
n Что делать при передаче экземпляров параметризованных типов в методы, т.е. как писать сигнатуру?
n Для этого используется метасимвол, обозначающий произвольный тип-параметр
class Generic<T> {
...
boolean compare(Generic<?> o) {
return o.getObj() == obj;
}
Метасимвол с ограничениями
n Ограничение сверху
<? extends super>
Тип super допускается
n Ограничение снизу
<? super sub>
Тип sub не допускается
Параметризованные методы
n Методы могут иметь собственные типы-параметры
n Фактические аргументы, передаваемые в формальные аргументы, имеющие тип-параметр, будут проверяться на соответствие типу, причем на этапе компиляции
n Пример метода
public static <T extends Comparable<T>> T min(T[] v) {
T min = v[0];
for (int i = 1; i < v.length; i++)
if (min.compareTo(v[i]) > 0)
min = v[i];
return min;
}
n Пример использования
System.out.println(min(new Integer[] {10, 15, 5}));
Вопрос 64Настраиваемые типы. Особенности и внутренняя реализация. 24-27 Лекция Collections Framework
Ряд особенностей
n Конструкторы могут быть параметризованными (даже если сам класс таковым не является)
n Интерфейсы могут быть параметризованными
n Нельзя создавать объекты, используя типы-параметры
n Статические члены класса не могут использовать его типы-параметры
n Настраиваемый класс не может расширять класс Throwable
n От настраиваемых типов можно наследовать, есть ряд особенностей
Ряд особенностей
n Нельзя создать массив типа-параметра
class Generic<T> {
T[] vals; //OK
Generic(T[] nums) {
//vals = new T[10]; // Не есть правильно !
vals = nums; //OK
}
}
n Массивов элементов конкретной версии параметризованного типа не бывает
//Generic<Integer>[] gens = new Generic<Integer>[10];//Nicht OK
Generic <?>[] gens = new Generic <?>[10];
И как же это работает?
n Механизм стирания
l В реальном байт-коде никаких настраиваемых типов в целом-то и нет…
l Информация о настраиваемых типах удаляется на стадии компиляции
l Именно компилятор осуществляет контроль безопасности приведения типов
l А внутри после компиляции все те же «обобщенные» классы, явные приведения типов и прочее, и прочее…
Ошибки неоднозначности
n Логически правильный» код
public class Test <T> {
T first(T[] arr) {
return arr[0];
}
Object first(Object[] arr) {
return arr[0];
}
}
n Оказывается неверным с точки зрения компилятора
Test.java:6: first(T[]) is already defined in Test
Object first(Object[] arr) {
^
n И это – самый простой пример…
Вопрос 65 Автоупаковка и автораспаковка. 28-29 Лекция Collections Framework
Дата: 2019-07-30, просмотров: 239.