Миграционная совместимость. Обобщения не были частью языка с самого начала, и появились только в версии
1.5. Стирание необходимо, чтобы можно было использовать обобщенный клиентский
код с необобщенными библиотеками и наоборот.
Расплата за стирание
Операции, для выполнения которых нужно точно знать типы времени
выполнения, работать не будут.
-
Приведение типов:
(T) var;
-
Операция
instanceof
:
varue instaceof T;
-
Операция new
T var = new T();
T[] array = new T[size]
-
Создание массива конкретного типа:
Type arr = new Type[10];
Применение параметризованных типов в классах
106
class Name {
private T t;
private E e;
public Name(T t, E e) { this.t = t; this.e = e; }
public T getT() { return t; }
public void setE(E e) { this.e = e;}
}
class test {
public static void main(String[] args){
Name obj1 = new NameInteger>("string", 3);
String a = obj1.getA();
obj1.setB(10);
Name obj2 = new Name(3, new ArrayList(3));
Integer i = (Integer)obj2.getA();
}
}
Особенности параметризованных типов. Тип можно указывать не только для классов и интерфейсов, но и методов и
конструкторов (не зависимо от того, параметризирован класс и интерфейс или нет. В
этом случае тип указывается перед возвращаемым значением. При использовании
одинаковых идентификаторов типа у класса и у метода или конструктора, тип
последних скрывает тип класса (интерфейса).
Простые параметризованные типы в методах и конструкторах
interface GIN {
void meth1 (T t); //
Тип
-
параметр
метода
скрывает
тип
интерфейса
E meth2 (E e); //
У
метода
свой
тип
-
параметр
T meth3 (T t); //
Метод
использует
тип
интерфейса
}
class GCL implements GIN {
T t;
public GCL(T t){ } //
Конструктор
скрывает
тип
класса
public GCL (E e, T t) { } //
У
конструктора
свой
тип
и
он
//
использует
тип
класса
@Override
107
public void meth1(T1 t1) { } //
реализация
метода
без
путаницы
//
с
именами
типов
-
параметров
@Override
public E meth2(E e) {return e; }
@Override
public T meth3(T t) {return null;}
}
Если информация о типе стирается, как вызвать определенный метод у объекта
имеющего тип – параметр?
class GenericSpeaker {
T source;
public void giveVoice() {
//source.say();
ошибка
компиляции
}
}
Ограниченные типы
interface Speaker {
void say()
}
class Cat implements Speaker{
public void say() { System.out.println("maaauuuu"); }
}
class GenericSpeaker {
T source;
public void giveVoice() {
source.say();
}}
Ограничение типа позволяет использовать у ссылок методы и поля, доступные
в типе-ограничителе. Типы, не наследующие от указанного, не могут быть
использованы при создании объектов.
Class NameInterface1 & Interface2 & … > {...}
Как имя типа может быть указан 1 класс и множество интерфейсов,