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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

II: generics/Fi1ledListMaker java

import java.util.*;

public class FilledListMaker<T> { List<T> create(T t, int n) {

List<T> result = new ArrayList<T>; for(int i = 0: i < n; i++)

result.add(t); return result:

}

public static void main(String[] args) {

FilledListMaker<String> stringMaker =

new Fi11edListMaker<String>; List<String> list = stringMaker.createC'Hello", 4): System.out.pri ntln(1i st);

}

} /* Output:

[Hello, Hello. Hello. Hello]

*lll:~

Хотя

компилятор ничего не может знать о Т в create, он все равно способен проверить — на стадии компиляции — что заносимые в result объекты имеют тип Т и согласуются с ArrayList<T>. Таким образом, несмотря на то что стирание удаляет информацию о фактическом типе внутри метода или класса, компилятор все равно может проверить корректность использования типа в методе или классе.

Так как стирание удаляет информацию о типе внутри тела метода, на стадии выполнения особую роль приобретают границы — точки, в которых объект входит и выходит из метода. Именно в этих точках компилятор выполняет проверку типов и вставляет код преобразования. Рассмотрим следующий ^параметризованный пример:

// generics/SimpleHolder.java

public class SimpleHolder { private Object obj;

public void set(Object obj) { this.obj = obj; } public Object get О { return obj; } public static void main(String[] args) {

SimpleHolder holder = new SimpleHolder.

holder set("Item"),

String s = (String)holder getO:

}

} ///-

Декомпилировав результат командой javap -с SimpleHolder, мы получим (после редактирования):

public

void set(java lang Object);

0

aload_0

1:

aload 1

2:

putfield #2; II Поле obj.Object;

5.

return

public

java lang.Object getO.

0;

aload 0

1-

getfield #2; II Поле obj-Object,

4

areturn

public

static void main(java 1ang.String[]);

0:

new #3, // Класс SimpleHolder

3-

dup

4:

invokespecial #4; // Метод "<init>".V

7.

astore_l

8-

aload 1

9.

ldc #5; II String Item

11

invokevirtual #6; // Метод set (Object;)V

14:

aload_l

15.

invokevirtual #7, // Метод get:Object:

18;

checkcast #8, //'Класс java/lang/String

21:

astore_2

22.

return

Методы set и get просто записывают и читают значение, а преобразование проверяется в точке вызова get.

Теперь включим параметризацию в приведенный фрагмент:

II: generics/GenericHolder.java

public class GenericHolder<T> { private T obj,

public void set(T obj) { this.obj = obj; } public T get

О { return obj; } public static void main(String[] args) { GenericHolder<String> holder =

new GenericHolder<String>; holder.set("Item"); String s = holder.get О;

}

Необходимость преобразования выходного значения get отпала, но мы также знаем, что тип значения, передаваемого set, проверяется во время компиляции. Соответствующий байт-код:

public void set(java.lang.Object);

0:

aload_0

1:

aload_l

2:

putfield #2; // Поле obj:0bject;

5:

return

public java.lang.Object getO;

0:

aload_0

1:

getfield #2; // Поле obj:0bject;

4:

areturn

public static void main(java.lang.String[]);

0.

new #3; // Класс GenericHolder

3:

dup

4:

invokespecial #4; // Метод "<init>"-V

7:

astore_l

8:

aload_l

9:

ldc #5; // String Item

11

invokevirtual #6; II Метод set:(Object;)V

14

aload_l

15

invokevirtual #7; // Метод get:OObject:

18

checkcast #8; // Класс java/lang/String

21

astore_2

22

return

Как видите, байт-код идентичен. Дополнительная работа по проверке входного типа set выполняется компилятором «бесплатно». Преобразование выходного значения get по-прежнему сохранилось, но, по крайней мере, вам не приходится выполнять его самостоятельно — оно автоматически вставляется компилятором.

Компенсация за стирание

Как мы видели, в результате стирания становится невозможным выполнение некоторых операций в параметризованном коде. Все, для чего необходима точная информация о типе во время выполнения, работать не будет:

//: generics/Erased.java // {CompileTimeError} (He компилируется)

public class Erased<T> {

private final int SIZE = 100: public static void f(Object arg) { if(arg instanceof T) {} T var = new TO; T[] array = new T[SIZE]; T[] array = (T)new Object[SIZE]

}

} Hi

ll Ошибка 11 Ошибка II Ошибка ; 11 Предупреждение

Иногда такие проблемы удается обойти на программном уровне, но в отдельных случаях стирание приходится компенсировать посредством введения метки типа. Другими словами, вы явно передаете объект Class для своего типа.

Например, попытка использования instanceof в предыдущем примере завершилась неудачей из-за того, что информация о типе была стерта. При введении метки типа вместо instanceof можно использовать динамический метод islnstance:

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

Банковское право

Рождественская Татьяна Эдуардовна
Деловая литература:
банковское дело
5.00
рейтинг книги
Банковское право

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

Трофимов Ерофей
Фантастика 2025. Компиляция
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Фантастика 2025-31. Компиляция. Книги 1-27

Егерь. Сердце стаи. Книга 5

Скиба Николай
5. Зверолов
Фантастика:
рпг
фэнтези
фантастика: прочее
попаданцы
6.80
рейтинг книги
Егерь. Сердце стаи. Книга 5

Газлайтер. Том 9

Володин Григорий Григорьевич
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Том 2. Рассказы и пьесы 1904-1907

Андреев Леонид Николаевич
2. Собрание сочинений в шести томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 2. Рассказы и пьесы 1904-1907

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Интернет-журнал "Домашняя лаборатория", 2008 №2

Журнал «Домашняя лаборатория»
Дом и Семья:
хобби и ремесла
сделай сам
5.00
рейтинг книги
Интернет-журнал Домашняя лаборатория, 2008 №2

Неожиданность

Попов Борис
Фантастика:
альтернативная история
5.00
рейтинг книги
Неожиданность

Коротков

Гладков Теодор Кириллович
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Коротков

Князь Андер Арес 3

Грехов Тимофей
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Князь Андер Арес 3

Болшевцы

Сборник
Документальная литература:
биографии и мемуары
6.00
рейтинг книги
Болшевцы

Том 4. Повести и рассказы, статьи 1844-1854

Тургенев Иван Сергеевич
4. Собрание сочинений в двенадцати томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 4. Повести и рассказы, статьи 1844-1854

Советы по Delphi. Версия 1.4.3 от 1.1.2001

Озеров Валентин
Компьютеры и Интернет:
программирование
5.00
рейтинг книги
Советы по Delphi. Версия 1.4.3 от 1.1.2001

Граф в законе (сборник)

Смирнов Владимир
Терра - детектив
Детективы:
криминальные детективы
5.00
рейтинг книги
Граф в законе (сборник)