Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
java1_2013_2014 / java14.pptx
Скачиваний:
133
Добавлен:
16.04.2015
Размер:
129.56 Кб
Скачать

JAVA-ТЕХНОЛОГИЯ

Сафонов Владимир Олегович

Профессор кафедры информатики, руководитель лаборатории Java- технологии (http://polyhimnie.math.spbu.ru/jtl)

Email: vosafonov@gmail.com

Лекция 14

Java generics:

Различные параметризованные типы разделяют один и тот же класс

Пример (Sun) :

Vector<String> x = new Vector<String>(); Vector<Integer> y = new Vector<Integer>(); boolean b = x.getClass() == y.getClass();

Вданном примере значение булевской переменной b – истина, так как различные типы

Vector<String> и Vector<Integer> разделяют один и тот же класс Vector во время выполнения

(C)В.О. Сафонов.

2013

Ограничения на тип-параметр

<T extends C1 & … & Cn>

T – тип-параметр

C1, … Cn – имена классов или интерфейсов

Ограничения задают требуемое поведение типа-параметра, т.е. набор его операций (методов), который может использоваться при реализации типа, параметризуемого типом T

T – типовая переменная (type variable)

Вариант без ограничений: < T >

(C) В.О. Сафонов. 2013

Пример: параметризованный тип с ограничениями и его реализация

package generics_test;

public class Main {

public static class Stack <T extends Comparable<T> & java.io.Serializable> { public void push (T x) {

int i = x.compareTo(x); System.out.println("i=" + i);

}

public T pop () { return null; }

}

public Main() { }

public static void main(String[] args) {

Stack <String> s = new Stack <String>();

// Stack <Integer> I = s; -- ошибка: incompatible types s.push("abc");

}

}(C) В.О. Сафонов. 2013

Пояснения к примеру

Определяется параметризованный тип Stack

Ограничения на тип-параметр: он должен реализовывать два интерфейса:

- параметризованный интерфейс Comparable<T>, содержащий единственный метод:

int compareTo(T obj)

Предполагаемая семантика метода:

результат операции t1.compareTo(t2) < 0, если t1 “меньше” t2;

== 0, если t1 “равно” t2; > 0, если t1 “больше” t2 Может использоваться, например, при сортировке

- интерфейс-маркер Serializable, т.е. быть сериализуемым

Все параметризации класса Stack разделяют этот класс (он существует в единственном экземпляре и не “размножается”, как template C++, при каждой параметризации). Но, например,

Stack<String> и Stack<Integer> - несовместимые типы

(C) В.О. Сафонов. 2013

Реализация примера Stack

(байт-код получен инструментом jclasslib 3.0 фирмы ej-technologies GMbH)

Компилятор генерирует два класс-файла: Main.class и Main$Stack.class

Байт-код метода main:

0 new #2 <generics_test/Main$Stack>

3 dup

4 invokespecial #3 <generics_test/Main$Stack.<init>>

7 astore_1

8 aload_1

9 ldc #4 <abc>

11 invokevirtual #5 <generics_test/Main$Stack.push>

14return

(C)В.О. Сафонов. 2013

Пояснения к байт-коду метода main

#2, #3, … - ссылки на константный пул (в нем размещаются константы, и типы, и т.д.)

Invokespecial, invokevirtual – формы вызова метода

aload_1, astore_1 – команды загрузки в стек значения локальной переменной номер 1 и записи содержимого вершины стека в локальную переменную номер 1. Локальные переменные нумеруются; номер 0 занят параметром args

ldc – загрузка в стек константы (строки)

Содержательно байт-код ничем не отличается от байт-кода без использования

(C) В.О.параметризованныхС фонов. типов

2013

Байт-код методов класса Stack

Метод push:

0 aload_1

1 aload_1

2 invokeinterface #2 <java/lang/Comparable.compareTo> count 2

7 istore_2

8 getstatic #3 <java/lang/System.out>

11 new #4 <java/lang/StringBuilder>

14dup

15invokespecial #5 <java/lang/StringBuilder.<init>>

18ldc #6 <i=>

20invokevirtual #7 <java/lang/StringBuilder.append>

23iload_2

24invokevirtual #8 <java/lang/StringBuilder.append>

27invokevirtual #9 <java/lang/StringBuilder.toString>

30invokevirtual #10 <java/io/PrintStream.println>

33return

(C)В.О. Сафонов. 2013

Пояснения к байт-коду метода push

Идея реализации обращения к операциям типа- параметра T: благодаря объектно-ориентированной природе Java, в частности, понятию интерфейса и

реализации интерфейса, необходимые операции берутся из типа аргумента x

Фактический тип аргумента x (String) имеет свою VMT

(virtual method table), в которой, в частности, содержится метод compareTo. Команда invokeinterface

вызывает этот метод

Благодаря VMT, нет необходимости в явной передаче указателя на метод compareTo в качестве дополнительного аргумента

Вывод значения i: для оптимизации (во избежание образования мусора) вместо класса String используется

класс StringBuilder

(C) В.О. Сафонов.

2013Проблема такой реализации: “type erasure” (стирание

Параметризация и подтипы

Если: класс S – подкласс класса C: public class S extends C { … }, G – параметризованный тип: public class G<T>,

то G<S> - НЕ подтип типа G<C>, т.е. присваивания: p: G<C>; q: G<S>; p = q; q = p;

-ОШИБОЧНЫ (несовместимость типов)

Аналогично, если G1 – подкласс класса G:

public class G1<T> extends G<T> { … }

то типы G1<C> и G<C> также НЕСОВМЕСТИМЫ: r: G1<C>; s: G<C>; r = s; s = r; - ОШИБОЧНЫ

Пример (G.Bracha, Sun) : Если Driver – подкласс класса Person, то List <Driver> - НЕ подкласс класса List <Person>:

список водителей не может рассматриваться как список людей, иначе в этот список могут быть внесены новые люди, не имеющие водительских прав

(C) В.О. Сафонов. 2013

Соседние файлы в папке java1_2013_2014