2016-10-18 4 views
3

У меня есть классИнстанцирование из родового объекта с групповым символом

public class OrderedBox<T> {}  


Компилятор не позволяет создать члена/локальную переменную, как это.

OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>(); 
List<? extends T> testItems2 = new ArrayList<? extends T>(); 

Ее причина понятно во время выполнения, это не гарантирует тип объектов (верхний, ограниченный Т) будет вставлено и будет игнорировать типобезопасность.

Но это позволяет создавать переменную-член/локальную переменную, подобную этим. Почему и как это можно сделать?

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>(); 



Примечание: У меня есть это сомнение, проходя через http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index1.html

Вероятные дублей:
Creating new generic object with wildcard
Generics wildcard instantiation

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

+0

Два вопроса: какая версия Java вы используете, и почему вы не используете алмазный ''> оператор, который бы позаботился об этой проблеме? – Makoto

+0

Первый ответ на указанную ссылку «Создание нового универсального объекта с помощью подстановочного знака» объясняет причину, по которой вы не разрешены в первый раз (потому что вы не говорите, для какого класса будет создан объект testItems1) и почему вам разрешено во второй раз (потому что вы сообщают, что список должен иметь тип OrderedBox) –

+0

@Makoto, 1st: Java7. 2: Спасибо, <> решает. Но мой вопрос - почему он это разрешает? – arc

ответ

4

Ответ на вариации одной линии на самом деле объясняется второй SO вопрос вы писали: Generics wildcard instantiation

Один лайнер делает объявить собой тип OrderedBox, но не создает его экземпляр.

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>(); 

Это говорит о том, что у вас будет OrderedBox, но он не говорит, какой из них. Вы будете иметь проблемы при попытке создать экземпляр как

testItems.add(new OrderedBox<? extends T>()) 

Потому что в то время, вы будете фиксировать тип.

+0

Ваше объяснение действительно помогло. Я пробовал, и это сработало, как вы упомянули. Но я хотел бы знать, как это работает во время выполнения :). Редактирование вопроса – arc

+0

Java-компилятор делает стирание типа (это ключевое слово для поиска). Таким образом, это преобразуется в 'OrderedBox ' во время выполнения, и вы можете что-то вкладывать в него теоретически. Но компилятор не позволит вам делать это заранее. – Simon

0

Ваш список объект Сумка, где вы можете хранить много OrderedBox объектов

private List<OrderedBox<? extends T>> testItems = new ArrayList<OrderedBox<? extends T>>(); 

Это не имеет значения, что это OrderedBox есть в нем во время компиляции, используя этот вид синтаксиса вызовет проблемы, если вы попробуйте вставить объекты в этот список.

Вы должны использовать дженерики (шаблонные) при объявлении класса, Но При создании объектов для этого класса вы должны быть конкретными, как

private List<OrderedBox<Object>> testItems = new ArrayList<OrderedBox<Object>>(); 

Компилятор не позволит

OrderedBox<? extends T> testItems1 = new OrderedBox<? extends T>(); 

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

 Смежные вопросы

  • Нет связанных вопросов^_^