Философия Java3
вернуться

Эккель Брюс

Шрифт:

Может создаться впечатление, что низкоуровневый Holder и Holder<?> — приблизительно одно и то же. Однако метод unboundedArgs демонстрирует различия между ними — в нем выявляются те же проблемы, но информация о них выдается в виде ошибок, а не предупреждений, поскольку низкоуровневый Holder может содержать разнородные комбинации типов, тогда как Holder<?> содержит однородную коллекцию одного конкретного типа.

В exactl и exact2 используются точные параметры типов (то есть без метасимволов). Мы видим, что exact2 обладает иными ограничениями, нежели exactl, из-за дополнительного аргумента.

В wildSubtype ограничения на тип Holder опускаются до Holder с элементами любого типа, удовлетворяющими условию extends Т. И снова это означает, что Т может быть типом Fruit, a holder сможет вполне законно стать Holder <Apple>. Чтобы предотвратить возможное размещение Orange в Holder<Apple>, вызовы set (и любых других методов, получающих в аргументах параметр типа) запрещены. Однако мы знаем, что все объекты, полученные из Holder<? extends Fruit>, по меньшей мере, являются Fruit, поэтому вызов get (или любого метода с возвращаемым значением параметра типа) допустим.

Реализация параметризованных интерфейсов

Класс не может реализовать две разновидности одного параметризованного интерфейса — вследствие стирания они будут считаться одним и тем же интерфейсом. Пример конфликта такого рода:

II: generics/MultiplelnterfaceVariants.java

II {CompileTimeError} (He компилируется)

interface Payable<T> {}

class Employee implements Payable<Employee> {}

class Hourly extends Employee

implements Payable<Hourly> {} ///:-

Класс Hourly компилироваться не будет, потому что стирание сокращает Payable<Employee> и Payable<Hourly> до Payable, а в приведенном примере это означало бы двукратную реализацию одного интерфейса. Интересная подробность: если удалить параметризованные аргументы из обоих упоминаний Payable, как это делает компилятор при стирании, программа откомпилируется.

Преобразования типов и предупреждения

Преобразование типа или instanceof с параметром типа не приводит ни к какому эффекту. В следующем контейнере данные хранятся во внутреннем представлении в форме Object и преобразуются к Т при выборке:

//. generics/GenericCast.java

class FixedSizeStack<T> { private int index = 0; private Object[] storage; public FixedSizeStackOnt size) {

storage = new Object[size];

}

public void push(T item) { storage[index++] = item; }

@SuppressWarni ngs("unchecked")

public T popО { return (T)storage[--index], }

}

public class GenericCast {

public static final int SIZE = 10; public static void main(String[] args) { FixedSizeStack<String> strings =

new FixedSizeStack<String>(SIZE); for (String s • "А В С D E F G H I J".splitC' "))

strings.push(s), for(int i = 0. i < SIZE; i++) {

String s = strings pop; System.out.print(s + " ");

} /* Output:

JIHGFEDCBA

*///:-

Без директивы @SuppressWarnings компилятор выдает для рор предупреждение о «непроверенном преобразовании». Вследствие стирания он не знает, безопасно преобразование или нет, поэтому метод рор никакого преобразования не выполняет. Т стирается до первого ограничения, которым по умолчанию является Object, так что рор на самом деле преобразует Object в Object.

Перегрузка

Следующий пример не компилируется, хотя на первый взгляд выглядит вполне разумно:

// generics/UseList java

// {CompileTimeError} (He компилируется)

import java.util.*;

public class UseList<W.T> { void f(List<T> v) {}

void f(List<W> v) {}

} III ~

Перегрузка метода создает идентичную сигнатуру типа вследствие стирания. В таких случаях следует определять методы с различающимися именами:

II. generics/UseList2 java

import java util.*;

public class UseList2<W.T> { void fl(List<T> v) {} void f2(List<W> v) {}

} III.-

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

Резюме

Мне довелось работать с шаблонами С++ с момента их появления. Скорее всего, приведенный далее аргумент я выдвигал в спорах чаще, чем большинство моих единомышленников. Лишь недавно я задумался над тем, насколько в действительности справедлив этот аргумент, — сколько раз проблема, которую я сейчас опишу, проникала в рабочий код?

  • Читать дальше
  • 1
  • ...
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • ...

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • help@private-bookers.win

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