
- •JAVA-ТЕХНОЛОГИЯ
- •Нововведения в язык в Java 1.5
- •Перечисления (type-safe enums)
- •Подход к перечислениям в Java
- •Пример 1: перечисления в Java
- •Пояснение к примеру 1 (перечисления в Java)
- •Пример 2: Тип-перечисление с методом
- •Пояснения к примеру 2 (тип-перечисление с методом)
- •Роль конструктора в перечислениях
- •Параметризованные типы (generics)
- •История generics (продолжение)
- •Основы generics в языке Java (JSR 14, 1999 – 2004,
- •Пояснения к примеру 1 (Java generics)
- •Параметризованные методы. Ограничения на типы-параметры
- •Пояснения к примеру 2

JAVA-ТЕХНОЛОГИЯ
Сафонов Владимир Олегович
Профессор кафедры информатики, руководитель лаборатории Java- технологии (http://polyhimnie.math.spbu.ru/jtl)
Email: vosafonov@gmail.com
Лекция 13

Нововведения в язык в Java 1.5
Перечисления (enumerations)
Параметризованные классы и интерфейсы (generics)
Аннотации (annotations)
Расширенная форма цикла for – цикл по коллекции
Методы с переменным числом аргументов (varargs)
Статический импорт (static import)
Неявные преобразования boxing/unboxing (уже рассмотрены ранее)
(C)В.О. Сафонов.
2013

Перечисления (type-safe enums)
История:
Впервые перечисления были введены в Паскале и C (1970 г.)
В Паскале перечисление – новый тип, не идентичный никакому
другому; его значения – именованные константы данного типа:
type Mood = (Good, Bad, Blue); Color = (Red, Green, Blue);
{ Blue – ошибка: повторное описание } var m: Mood; c: Color;
begin c:= Red; m:= Good; c:= m; { ошибка } m:= 0; { ошибка! } end
В Паскале тип-перечисление – простой; представляется целым, но не совместим с целым типом; тип-перечисление может быть типом индекса массива
В Си перечисление – это перечисление именованных констант,
значения которых – целые числа (это менее надежно)
(C) В.О. Сафонов. 2013

Подход к перечислениям в Java
Отсутствие перечислений в Java (до 1.5) было крайне неудобно: их приходилось моделировать с помощью классов с константами. Поэтому было специфицировано и реализовано в Java 1.5 JSR 201 – введение enums в Java
В Java принят безопасный подход: каждое перечисление – новый тип
Перечисления в Java – гораздо сложнее по семантике, чем в Паскале; перечисление – это не простой тип, а класс, объектами которого могут
быть только явно перечисленные константы данного типа
Тип-перечисление может описывать не только сами значения данного типа; в нем могут быть также определены методы
Возможен цикл по значениям типа-перечисления (расширенная форма цикла for)
В разных типах-перечислениях имена значений (Blue и т.д.) могут
повторяться. Обращение к значениям: c = Color.Blue;
Присваивать значение типа-перечисления, а также целое значение переменной другого типа-перечисления запрещено
Сравнение с .NET: в языке C# семантика перечислений близка к семантике Java (safe); но в общей системе типов (CTS) перечисление –
подмножество значений базового (целого) типа. В .NET CTS перечисления относятся к типам-значениям (value types)
(C)В.О. Сафонов.
2013

Пример 1: перечисления в Java
package enumtest;
public class Main {
public enum Color {RED, YELLOW, BLUE}
public enum TrafficLights {RED, YELLOW, GREEN}
public Main() { }
public static void main (String [] args) { Color c;
TrafficLights t; c = Color.RED;
t = TrafficLights.RED;
/* c = t; t = c; c = 0; -- ошибки! */ System.out.println(" c = " + c + " t = " + t); for (Color clr : Color.values() ) {
System.out.println(clr);
}
} // main
}(C) В.О. Сафонов. 2013

Пояснение к примеру 1 (перечисления в Java)
В классе Main определены два типа- перечисления Color и TrafficLights; у них есть значения с одним и тем же именем
Значение типа-перечисления используется с указанием его типа: TrafficLights.RED
Присваивания значений несовместимых типов (целого и другого типа-перечисления) запрещены
Выполняется цикл по значениям типа- перечисления (это очень удобно; в Паскале такой возможности нет)
(C)В.О. Сафонов.
2013

Пример 2: Тип-перечисление с методом
package enumtest; public class Main {
public enum TrafficLights {RED, YELLOW, GREEN; public void go () {
if (this == RED) { System.out.println("Stop!");
}else if (this == YELLOW) { System.out.println("Wait a moment...");
}else {
System.out.println("You may go now");
}
}
}
public Main() { }
public static void main (String [] args) {
for (TrafficLights tl : TrafficLights.values() ) { System.out.println(tl);
tl.go();
}
} // main
(C)} В.О. Сафонов. 2013

Пояснения к примеру 2 (тип-перечисление с методом)
Определяется тип-перечисление TrafficLights с методом go – проверка возможности перехода по текущему сигналу светофора
Данный метод используется в цикле по значениям типа TrafficLights
Использование операции == разрешено спецификацией Java, так как все объекты данного типа явным образом перечислены в его определении
Описать для типа TrafficLights конструктор – разрешено, но использовать для него new -
(C)запрещеноВ.О. Сафонов. (!) 2013

Роль конструктора в перечислениях
Роль конструктора в том, чтобы инициализировать дополнительные поля, ассоциируемые с константой типа-перечисления, которое может иметь аргументы (значения). Конструктор по умолчанию – private и не имеет аргументов. Если он с аргументами, то им присваиваются значения констант, ассоциируемых с данным значением типа-перечисления
Пример (Sun) :
public enum Planet {
MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e+26, 6.0268e7), URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7), PLUTO (1.27e+22, 1.137e6);
/* устарело: Плутон разжалован в астероид */ private final double mass;
private final double radius; Planet(double mass, double radius)
{ this.mass = mass; this.radius = radius; } …
}
(C) В.О. Сафонов. 2013

Параметризованные типы (generics)
Определение и история generics
Generics – возможность описания модуля, параметризованного
используемыми в нем типами (например, типа Stack,
параметризованного типом элемента).
Цель generics – code reusability: сделать код более общим и избежать его дублирования; разрабатывать один более общий “родовой” (generic) модуль вместо нескольких аналогичных модулей, отличающихся только типами
Впервые generics были введены в языке CLU (B. Liskov, MIT, 1974) под названием параметризованные модули:
list = cluster [t: type] is create, const, car, cdr … t … t … end
list
В этом же языке CLU впервые были введены ограничения на типы-параметры (restrictions):
sort = proc <t: type> (a: array[t])
where t has lt: proctype(t, t) returns (bool) … a[i] < a[j] …
(C)endВ.О. Сафонов.
2013В CLU также были параметры-константы (например,
максимальный размер стека), которых сейчас нет ни в Java, ни в