Читаем Философия Java3 полностью

public void put(int index, T item) { array[index] = item;

}

@SuppressWarnings("unchecked")

public T get(int index) { return (T)array[index]; }

@SuppressWarnings("unchecked")

public T[] rep О { продолжение &

return (T[])array; // Предупреждение: непроверенное преобразование

}

public static void main(String[] args) { GenericArray2 gai =

new GenericArray2(10); for(int i = 0: i < 10: i ++)

gai.put(i, i): for(int i = 0: i < 10; i ++)

System.out.print(gai.get(i) + " "); System.out.printlnO; try {

Integer[] ia = gai.rep(); } catch(Exception e) { System.out.printin(e); }

}

} /* Output: (Sample)

0 12 3 4 5 6 7 8 9

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer,

На первый взгляд почти ничего не изменилось, разве что преобразование типа было перемещено. Без директив @SuppressWarnings вы по-прежнему будете получать предупреждения, но теперь во внутренней реализации используется Object[] вместо Т[]. При вызове get() объект преобразуется к Т; это правильный тип, поэтому преобразование безопасно. Но при вызове гер() снова делается попытка преобразования Object[] в Т[], которое остается неверным; в результате вы получите предупреждение во время компиляции и исключение во время выполнения. Не существует способа обойти тип базового массива, которым может быть только Object[]. У внутренней интерпретации array как Object[] вместо Т[] есть свои преимущества: например, вы с меньшей вероятностью забудете тип массива, что приведет к случайному появлению ошибок (впрочем, подавляющее большинство таких ошибок будет быстро выявлено на стадии выполнения).

В новом коде следует передавать метку типа. В обновленной версии Generic-Array выглядит так:

//: generics/Generic/\rrayWithTypeToken.java

import java.lang.reflect.*;

public class GenericArrayWithTypeToken { private T[] array; @SuppressWarni ngs("unchecked")

public GenericArrayWithTypeToken(CIass type, int sz) { array = (T[])Array.newInstance(type, sz);

}

public void put(int index, T item) { arrayCindex] = item;

}

public T get(int index) { return arrayCindex]; } // Expose the underlying representation: public T[] rep() { return array; } public static void main(String[] args) {

GenericArrayWithTypeToken gai =

new Generi cArrayWi thTypeToken( Integer.class, 10);

// This now works:

Integer[] ia = gai.rep();

}

} ///

Метка типа Class передается конструктору для восстановления информации после стирания, чтобы мы могли создать фактический тип нужного массива (предупреждения при преобразовании по-прежнему приходится подавлять @SuppressWarnings). Получив фактический тип, мы возвращаем его для получения желаемых результатов, как видно из main().

К сожалению, просмотрев исходный код стандартных библиотек Java SE5, вы увидите, что преобразования массивов Object в параметризованные типы происходят повсеместно. Например, вот как выглядит копирующий конструктор для создания ArrayList из Collection после некоторой правки и упрощения:

public ArrayList(Collection с) { size = c.sizeO;

elementData = (E[])new Object[size]; с.toArray(elementData):

}

В ArrayList.java подобные преобразования встречаются неоднократно. И конечно, при их компиляции выдается множество предупреждений.

Ограничения

Ограничения, уже упоминавшиеся ранее в этой главе, сужают круг параметров типов, используемых при параметризации. Хотя это позволяет предъявлять требования к типам, к которым применяется ваш параметризованный код, у ограничений имеется и другой, потенциально более важный эффект: возможность вызова методов, определенных в ограничивающих типах.

Поскольку стирание уничтожает информацию о типе, при отсутствии ограничений для параметров типов могут вызываться только методы Object. Но, если ограничить параметр подмножеством типов, вы сможете вызвать методы из этого подмножества. Для установления ограничений в Java используется ключевое слово extends. Важно понимать, что в контексте параметризации extends имеет совершенно иной смысл, нежели в обычной ситуации. Следующий пример демонстрирует основы установления ограничений:

//: generics/BasicBounds.java

interface HasColor { java. awt. Col or getColorO; }

class Colored { T item:

Colored(T item) { this.item = item; }

T getltemO { return item; }

// Ограничение позволяет вызвать метод:

java. awt. Col or colore) { return item.getColorO; }

}

class Dimension { public int x, y. z; }

// Не работает -- сначала класс, потом интерфейсы: // class ColoredDimensiол<Т extends HasColor & Dimension> {

// Несколько ограничений-

class ColoredDimension { T item:

Перейти на страницу:

Похожие книги

Access 2002: Самоучитель
Access 2002: Самоучитель

В книге рассматривается широкий круг вопросов, связанных с использованием программной среды Access 2002, которая является составной частью пакета Office 2002 и предназначена для создания банка данных в самых различных предметных областях.Подробно описывается методика проектирования объектов базы данных (таблицы, формы, отчеты, страницы доступа к данным, запросы, модули).Детально обсуждаются вопросы создания интегрированной базы данных в единой среде Access 2002: формирование БД с нуля, конвертирование в программную среду баз данных, созданных в ином программном окружении – Clarion, FoxPro.Особое внимание уделяется формированию разнообразных запросов к интегрированной базе данных Access 2002 с использованием языков программирования SQL, VBA и макросов.Приводятся общие сведения о возможностях языка обмена данными между различными компьютерами и приложениями (XML). Описываются возможности использования гиперссылок, связывающих базу данных с другими программными продуктами. Объясняется, как можно работать с базой данных Access 2002 без установки ее на компьютер, используя технологию ODBC (Open Data Base Connectivity). В приложениях приводятся количественные параметры Access 2002 и связанная с этой СУБД терминология.Предлагаемая книга будет полезна специалистам, занимающимся практической разработкой банков данных и приложений на их основе, а также студентам вузов, изучающим информатику.

Павел Юрьевич Дубнов

Программирование, программы, базы данных / ОС и Сети / Книги по IT