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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

//: generics/UnboundedWi1dcardsl.java

import java.util.*;

public class UnboundedWildcardsl {

static List listl;

static List<?> list2;

static List<? extends Object> list3;

static void assignldist list) { listl = list; 1i st2 = list;

// list3 = list; // Предупреждение: непроверенное преобразование // Обнаружен List, требуется List<? extends Object>

}

static void assign2(List<?> list) { listl = list; list2 = list; list3 = list;

}

static void assign3(List<? extends Object> list) { listl = list; list2 = list; list3 = list;

}

public static void main(String[] args) { assignl(new ArrayListO): assign2(new ArrayList); // assign3(new ArrayListO); //

Предупреждение-// Непроверенное преобразование. Обнаружен- ArrayList // Требуется: List<? extends Object> assignl(new ArrayLi st<String>0); assign2(new ArrayList<String>0); assign3(new ArrayList<String>0); // Приемлемы обе формы-List<?> wildList = new ArrayListO; wildList = new ArrayList<String>; assignl(wildList); assign2(wildList); assign3(wildLi st);

}

} ///:-

Во многих ситуациях, подобных рассмотренной, для компилятора совершенно не существенно, используется низкоуровневый тип или <?>. Конструкцию <?> можно считать обычным украшением; впрочем, она обладает некоторой практической ценностью, потому что фактически означает: «Код написан с учетом параметризации Java, и здесь эта конструкция означает не то, что я использую низкоуровневый тип, а то, что параметр параметризации может содержать произвольный тип».

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

//: generics/UnboundedWi1dcards2.java

import java.util.*;

public class UnboundedWildcards2 { static Map mapl; static Map<?.?> map2; static Map<String,?> map3; static void assignlCMap map) { mapl = map; } static void assign2(Map<?,?> map) { map2 = map; } static void assign3(Map<String,?> map) { map3 = map; } public static void main(String[] args) { assignl(new HashMapO); assign2(new HashMapO); // assign3(new HashMapO); // Предупреждение: // Непроверенное преобразование. Обнаружен: HashMap // Требуется: Map<String,?> assignl(new HashMap<String,Integer>); assign2(new HashMap<String,Integer>); assign3(new HashMap<String.Integer>0):

}

} ///-

Когда в записи используются только неограниченные метасимволы, как в примере Мар<?,?>, компилятор не отличает такой тип от Map. Кроме того, пример UnboundedWildcardsl.java показывает, что компилятор по-разному интерпретирует List<?> и List<? extends Object>.

Ситуация осложняется тем, что компилятор не всегда интересуется различиями между List и List<?> (например), поэтому может показаться, что это одно и то же. В самом деле, поскольку параметризованный аргумент стирается до первого ограничения, List<?> кажется эквивалентным List<Object>, a List, по сути, тоже является List<Object> — однако ни одно из этих утверждений не является в полной мере истинным. List в действительности означает «низкоуровневый List,

содержащий любой тип Object», тогда как List<?> означает «не-низкоуровне-вый List, содержащий какой-то конкретный тип, хотя мы не знаем, какой именно».

Когда же компилятор различает низкоуровневые типы и типы с неограниченными метасимволами? В следующем примере используется класс Holder<T>, определение которого приводилось ранее. Класс содержит методы, получающие аргумент Holder, но в разных формах: в виде низкоуровневого типа, с конкретным параметром типа, с неограниченным метасимволом:

//: generics/Wildcards.java // Exploring the meaning of wildcards.

public class Wildcards {

// Низкоуровневый аргумент: static void rawArgs(Holder holder. Object arg) { // holder set(arg); // Предупреждение-// Непроверенный вызов set(T) как члена // низкоуровневого типа Holder // holder, set (new WildcardsO); // To же предупреждение

// Невозможно: нет информации о 'Т' // T t = holder.getO.

// Допустимо, но информация типа теряется Object obj = holder getO.

}

// По аналогии с rawArgsO, но ошибки вместо предупреждений, static void unboundedArg(Holder<?> holder. Object arg) { // holder.set(arg); // Ошибка: // set(capture of ?) in Holder<capture of ?> // не может применяться к (Object) // holder, set (new WildcardsO). // Та же ошибка

// Невозможно; нет информации о 'Т': // T t = holder.get;

// Допустимо, но информация типа теряется: Object obj = holder.getO;

}

static <T> T exactl(Holder<T> holder) { T t = holder.getO; return t;

}

static <T> T exact2(Holder<T> holder. T arg) { holder.set(arg); T t = holder.getO; return t;

}

static <T>

T wildSubtype(Holder<? extends T> holder. T arg) { // holder.set(arg); // Ошибка: // set(capture of ? extends T) in // Holder<capture of ? extends T> // cannot be applied to (T) T t = holder.getO; return t;

}

static <T>

void wildSupertype(Holder<? super T> holder, T arg) { holder.set(arg);

// T t = holder.getO; // Ошибка:

// Несовместимые типы: обнаружен Object, требуется T

// Допустимо, но информация типа теряется: Object obj = holder get О;

}

public static void main(String[] args) {

Holder raw = new Holder<Long>. // Или

raw = new Holder,

Holder<Long> qualified = new Holder<Long>, Holder<?> unbounded = new Holder<Long>. Holder<? extends Long> bounded = new Holder<Long>, Long Ing = 1L;

rawArgs(raw. Ing), rawArgs(qualified, Ing), rawArgs(unbounded. 1ng). rawArgs(bounded, Ing);

unboundedArg(raw, Ing), unboundedArg(qualified, Ing), unboundedArg(unbounded, Ing), unboundedArg(bounded, Ing),

// Object rl = exactl(raw); // Предупреждение // Непроверенное преобразование Holder в Holder<T> // Непроверенный вызов метода: exactlCHolder<T>) // применяется к (Holder) Long r2 = exactl(qualified),

Object r3 = exactl(unbounded), // Должен возвращать Object Long r4 = exactl(bounded),

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

Кодекс Охотника

Винокуров Юрий
1. Кодекс Охотника
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника

Кодекс Крови. Книга I

Борзых М.
1. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга I

Очерки времен и событий из истории российских евреев. 1945 – 1970 гг. Книга 6

Кандель Феликс Соломонович
Научно-образовательная:
история
5.00
рейтинг книги
Очерки времен и событий из истории российских евреев. 1945 – 1970 гг. Книга 6

Кодекс Охотника. Книга ХХХ

Винокуров Юрий
30. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга ХХХ

Журнал «Если», 2002 № 08

Андерсон Кевин Джей
114. Журнал Если
Фантастика:
научная фантастика
5.00
рейтинг книги
Журнал «Если», 2002 № 08

Возлюби болезнь свою

Синельников Валерий Владимирович
Научно-образовательная:
психология
7.71
рейтинг книги
Возлюби болезнь свою

Инженер Петра Великого 2

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

Форма жизни

Драу Михаэль
Фантастика:
боевая фантастика
киберпанк
7.62
рейтинг книги
Форма жизни

Мистика

Гейман Нил
Детективы:
классические детективы
исторические детективы
7.29
рейтинг книги
Мистика

Шайтан Иван 6

Тен Эдуард
6. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
7.00
рейтинг книги
Шайтан Иван 6

Товарищ "Чума" 2

lanpirot
2. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Товарищ Чума 2

Первый среди равных. Книга X

Бор Жорж
10. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Первый среди равных. Книга X

Черный Маг Императора 17

Герда Александр
17. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Черный Маг Императора 17

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства