Материал: 8

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

T[] array = new T[size]

-Создание массива конкретного типа:

Type<Integer> arr = new Type<Integer>[10];

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

class Name <T,E> { 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<String, Integer> obj1 = new Name<String,

Integer>("string", 3);

String a = obj1.getA(); obj1.setB(10);

Name obj2 = new Name(3, new ArrayList(3)); Integer i = (Integer)obj2.getA();

}

}

Особенности параметризованных типов

Тип можно указывать не только для классов и интерфейсов, но и методов и конструкторов (не зависимо от того, параметризирован класс и интерфейс или нет. В этом случае тип указывается перед возвращаемым значением. При использовании одинаковых идентификаторов типа у класса и у метода или конструктора, тип последних скрывает тип класса (интерфейса).

Простые параметризованные типы в методах и конструкторах

interface GIN <T> {

<T> void meth1 (T t); //Тип-параметрметода скрыватинтпетрфейса

<E> E meth2 (E e);

//Уметодасвойтип

-

параметр

//Методиспользуеттип

T meth3 (T t);

интерфейса

 

 

}

 

 

class GCL<T> implements GIN<T> {

 

T t;

}

//Конструктор

public <T> GCL(T t){

скрывтипклаетсса

 

} //У

public <E> GCL (E e, T t) {

конствойруктораионп

 

 

//используеттипкласса

@Override

public <T1> void meth1(T1 t1) { } //реализация методабезпутаницы //сименами типов-параметров

@Override

public <E> E meth2(E e) {return e; } @Override

public T meth3(T t) {return null;}

}

Если информация о типе стирается, как вызвать определенный метод у объекта имеющего тип – параметр?

class GenericSpeaker<T> { 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 extends Speaker> { T source;

public void giveVoice() { source.say();

}}

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

Class Name<T extends ClassName &

Interface1 & Interface2 & … > {...}

Как имя типа может быть указан 1 класс и множество интерфейсов, разделенных &. Как имя типа может быть указан ранее введенный параметр.

class GenericClass<T extends Comparable<T>> {...}

Маски

Что делать при передаче экземпляров параметризованных типов в методы, т.е. как писать сигнатуру? Для этого используется маска <?>, обозначающая произвольный тип-параметр.

class Generic<T> {

...

boolean compare(Generic<?> o) { return o.getObj() == obj;

}

Запись: boolean compare(Generic<?> o) {…}

означает, что в качестве параметра методу compare может быть передан тип Generic, параметризированный любым (а не конкретным, как если бы было Generic<T>) типом.

isEqual = ccompare(Generic<Runnable> o); isEqual = compare(Generic<StringBuilder> o); isEqual = compare(Generic<Calendar> o);

isEqual = compare(Generic<K> o); ompare(Generic<Integer> o); isEqual =

Маски позволяют задать отношение между параметризированными типами, а не типами-параметрами.

//пустьестьиерархия

(рисунок7.2)

class Fruit

{}

 

class Apple

extends Fruit{}

class

Citrus extends Fruit{}

class

Orange extends Citrus{}

Рисунок 8.2 – Иерархия классов

List<?> fruits = new ArrayList<Fruit>(); //Всем тоды add неработаютсошибкойкомпиляции

//add(capture<?>) в List неможетбытьпримененк

<Типдобавляемогообъекта > fruits.add(new Object());

fruits.add(new Fruit()); fruits.add(new Apple()); fruits.add(new Citrus()); fruits.add(new Orange());

//Этотмеработаетод

 

 

Object o = fruits.get(0);

get

//Остальныеметоды

get неработают,потомучто

возвращает Object инужноприводитьбъектунужному типу

Fruit f = fruits.get(0); Apple a = fruits.get(0);

Citrus c = fruits.get(0); Orange or = fruits.get(0); \\Методкомпилируется

public static List<?> getList() { List<Fruit> fruits = new ArrayList<Fruit>(); fruits.add(new Apple());

return fruits;

}

List<?> wFruits1 = getList(); \\Работает List<Fruit> wFruits2 = getList(); \\Ошибка компиляции

List<Apple> wFruits3 = getList(); \\Ошибка компиляции

public static void addToList(List<?> fruits) { \\add не работают все

fruits.add(new Fruit()); fruits.add(new Apple()); fruits.add(new Citrus()); fruits.add(new Orange());

Object o = fruits.get(0); \\работает

\\остальные get неработают

Fruit f = fruits.get(0); Citrus c = fruits.get(0); Orange or = fruits.get(0);

}

//всевызовыневызываютошибкикомпиляции

addToList(new ArrayList<Fruit>()); addToList(new ArrayList<Apple>()); addToList(new ArrayList<Citrus>()); addToList(new ArrayList());

Ограничение сверху Определяет отношение восходящего преобразования:

<? extends super>

Некоторый конкретный тип, параметр которого наследуется от super.