Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

}

} /* Output:

(Vehicle@llb86e7. Amphibian@35ce36, hi. 47) (Vehicle@757aef, Amphibian@d9f9c3. hi. 47) *///.-

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

А вот другой пример, который показывает, как легко строить сложные модели на основе параметризованных типов. Хотя каждый класс представляет собой автономный «строительный блок», их совокупность имеет сложную структуру. В данном случае моделируется магазин

с товарами, полками и стеллажами:

//. generics/Store.java

// Построение сложной модели на базе параметризованных контейнеров, import java util *. import net.mindview.util.*.

class Product {

private final int id. private String description; private double price;

public Product(int IDnumber, String descr. double price){ id = IDnumber; description = descr, this.price = price; System.out.pri ntln(toString);

}

public String toStringO {

return id + " + description + ", цена: $" + price;

public void priceChange(double change) { price += change,

}

public static Generator<Product> generator = new Generator<Product> {

private Random rand = new Random(47), public Product next О {

return new Product(rand nextlnt(lOOO), "Test",

Math round(rand nextDoubleO * 1000 0) + 0 99).

class Shelf extends ArrayList<Product> { public Shelf(int nProducts) {

Generators fill(this. Product generator. nProducts),

class Aisle extends ArrayList<Shelf> {

public AisleCint nShelves, int nProducts) { for(int i = 0; i < nShelves; i++) add(new Shelf(nProducts)),

class CheckoutStand {} class Office {}

public class Store extends ArrayList<Aisle> {

private ArrayList<CheckoutStand> checkouts =

new ArrayList<CheckoutStand>; private Office office = new OfficeO. public Store(int nAisles, int nShelves, int nProducts) { for(int i = 0; i < nAisles; i++)

add(new Aisle(nShelves. nProducts));

}

public String toStringO {

StringBuilder result = new StringBuilderO; for(Aisle a this)

for(Shelf s : a)

for(Product p • s) {

result.append(p); result.append("\n").

}

return result.toStringO.

}

public static void main(String[] args) {

System out.printin(new Store(14, 5. 10)).

}

} /* Output.

258: Test, цена: $400.99 861- Test, цена- $160.99 868: Test, цена: $417.99 207- Test, цена- $268.99 551- Test. цена. $114.99 278: Test, цена: $804.99

520. Test, цена: $554.99 140: Test, цена: $530.99

*///;-

Как видно из Store.toString, в результате мы получаем многоуровневую архитектуру контейнеров, не лишаясь преимуществ безопасности типов и управляемости. Впечатляет и то, что построение такой модели не потребует заметных умственных усилий.

Тайна стирания

Когда вы приступаете к более глубокому изучению контейнеров, некоторые обстоятельства на первых порах выглядят довольно странно. Например,

запись ArrayList.class возможна, а запись ArrayList<Integer>.class — нет. Или возьмите следующий фрагмент:

//: generics/ErasedTypeEquivalence.java import java.util.*;

public class ErasedTypeEquivalence {

public static void main(String[] args) {

Class cl = new ArrayList<String>.getClassO: Class c2 = new ArrayList<Integer>.getClass, System.out.pri ntln(cl == c2);

}

} /* Output:

true

*///.-

Было бы логично считать, что ArrayList<String> и ArrayList<Integer> — разные типы, поэтому их поведение должно различаться, и при попытке поместить Integer в ArrayList<String> результат (неудача) должен отличаться от того, который будет получен при помещении Integer в ArrayList<Integer> (успех). Однако эта программа создает впечатление, что эти типы одинаковы. Следующий пример еще сильнее запутывает ситуацию:

//. generics/Lostlnformation.java import java util *.

class Frob {} class Fnorkle {} class Quark<Q> {}

class Particle<POSITION,MOMENTUM> {}

public class Lostlnformation {

public static void main(String[] args) {

List<Frob> list = new ArrayList<Frob>; Map<Frob,Fnorkle> map = new HashMap<Frob.Fnorkle>; Quark<Fnorkle> quark = new Quark<Fnorkle>; Particle<Long.Double> p = new Particle<Long.Double>: System.out.pri ntln(Arrays.toStri ng(

list.getClass.getTypeParameters)); System out println(Arrays.toString(

map. getClassO .getTypeParametersO)). Л

продолжение &

System out pri ntinCArrays.toStri ng(

qua rk.getClass.getTypePa rameters));

System.out.pri ntinCArrays.toStri ng(

p.getClass.getTypePa rameters));

}

} /* Output: [E]

[K. V] [Q]

[POSITION. MOMENTUM] *///:-

Согласно документации JDK, Class.getTypeParameters «возвращает массив объектов TypeVariable, представляющих переменные типов, указанные в параметризованном объявлении...» Казалось бы, по ним можно определить параметры типов — но, как видно из результатов, вы всего лишь узнаете, какие идентификаторы использовались в качестве заполнителей, а эта информация не представляет особого интереса.

Мы приходим к холодной, бездушной истине:

Информация о параметрах типов недоступна внутри параметризованного кода.

Таким образом, вы можете узнать идентификатор параметра типа и ограничение параметризованного типа, но фактические параметры типов, использованные для создания конкретного экземпляра, остаются неизвестными. Этот факт, особенно раздражающий программистов с опытом работы на С++, является основной проблемой, которую приходится решать при использовании параметризации в Java.

Поделиться:
Популярные книги

Заложники пустоты

Абоян Виталий Эдуардович
Анклавы
Фантастика:
киберпанк
5.75
рейтинг книги
Заложники пустоты

Золото бунта

Иванов Алексей Викторович
Приключения:
исторические приключения
7.50
рейтинг книги
Золото бунта

Фея любви. Трилогия

Николаева Мария Сергеевна
141. В одном томе
Фантастика:
фэнтези
8.55
рейтинг книги
Фея любви. Трилогия

Парижские могикане. Том 1

Дюма-отец Александр
1. Могикане Парижа
Приключения:
исторические приключения
6.80
рейтинг книги
Парижские могикане. Том 1

Личный враг Бога

Кликин Михаил Геннадьевич
1. Личный враг Бога
Фантастика:
боевая фантастика
5.50
рейтинг книги
Личный враг Бога

Второгодка. Книга 5. Презренный металл

Ромов Дмитрий
5. Второгодка
Фантастика:
городское фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Второгодка. Книга 5. Презренный металл

Ник. Цикл

Ясинский Анджей
Ник
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ник. Цикл

Вечный. Книга VI

Рокотов Алексей
6. Вечный
Фантастика:
рпг
фэнтези
5.00
рейтинг книги
Вечный. Книга VI

"Фантастика 2025-123". Компиляция. Книги 1-32

Ипатова Наталия Борисовна
Фантастика 2025. Компиляция
Фантастика:
боевая фантастика
попаданцы
мистика
фэнтези
5.00
рейтинг книги
Фантастика 2025-123. Компиляция. Книги 1-32

Дважды одаренный. Том III

Тарс Элиан
3. Дважды одаренный
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
юмористическое фэнтези
5.40
рейтинг книги
Дважды одаренный. Том III

Психология взрослости

Ильин Евгений Павлович
Мастера психологии
Научно-образовательная:
психология
6.25
рейтинг книги
Психология взрослости

Краткий справочник необходимых знаний

Чернявский Андрей Владимирович
Домашняя библиотека
Научно-образовательная:
прочая научная литература
7.33
рейтинг книги
Краткий справочник необходимых знаний

Буря империи

Сай Ярослав
6. Медорфенов
Фантастика:
аниме
фэнтези
фантастика: прочее
эпическая фантастика
5.00
рейтинг книги
Буря империи

Пальмы в снегу

Габас Лус
Проза:
историческая проза
5.00
рейтинг книги
Пальмы в снегу