2013-02-20 5 views
2

Я много читал об этом, и я знаю, что:разница между списком и списком <?>

List<Object> listOfObject = new ArrayList<TYPE>(); // (0) 
//can only work for TYPE == Object. 
//if TYPE extends Object (and thus objects of type TYPE are Objects), 
//this is not the same with Lists: List<Type> is not a List<Object> 

Теперь я прочитал, что следующее нормально:

List undefinedList = new ArrayList<TYPE>(); // (1) 
//works for ANY type (except for primitives) 

И

List<?> wildcardList = new ArrayList<TYPE>(); // (2) 
//also works for ANY type (except for primitives) 

Тогда:

List undefinedlist = new ArrayList(); //no TYPE specified 
undefinedList.add(new Integer(1)); //WORKS 
undefinedList.add(new String("string")); //WORKS 

Однако:

List<?> wildcardList = new ArrayList<TYPE>(); //TYPE specified 
wildcardList.add(new TYPE(...)); //COMPILER ERROR 

пример:

List<?> wildcardList = new ArrayList<String>(); //TYPE specified 
wildcardList.add(new String("string")); //COMPILER ERROR: The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (String) 

Я понимаю, почему вы ничего не можете добавить к wildcardList, так как ее тип может быть что угодно. Однако почему вы можете добавить к undefinedList? Они кажутся одинаковыми & показывают одинаковое поведение, данное (1) и (2).

+0

Как с почти ЛЮБОЙ вопрос. Всегда лучше показать, что такое «ошибка компилятора» (текст ошибки). – billjamesdev

+0

'?' Не означает * ничего *, но ** неизвестен **. – m0skit0

+2

Возможный дубликат [java generics unbound wildcard vs raw type] (http: // stackoverflow.com/questions/14242174/java-generics-unbound-wildcard-vs-raw-type) –

ответ

0

«не определено» List содержит список типов Object который является отцом всех типов и, следовательно, List не типобезопасным (равноценно)

вот почему это:

List undefinedlist = new ArrayList<TYPE>(); //IS LIST OF OBJECTS 
undefinedList.add(new Integer(1)); //WORKS 
undefinedList.add(new String("string")); //WORKS 

хорошо .. работает!

+1

'Объект' не безопасен по типу? Извините, я не понял этого. – m0skit0

+0

Если это правда, то в чем разница между (0) и (1)? – joost

+0

Разница между тем, что одна равна нулю, а другая - 1? @joost –

0

Тип List<?> является общим: любой тип, который вы ставите вместо вопросительного знака, будет использоваться в методах списка. Таким образом, вы можете сделать list.add(item), и он позволит вам разместить String, если вы создали List<String>. Сначала введите безопасность.

List<String> list = new List<String>(); 
list.add("A");    // <-- Correct 
list.add((Integer)10);  // <-- Error, it is a List of Strings 

The List с другой стороны, позволяет любому Object положить в там. Итак, вы можете сделать List, поставить Giraffe, а затем Squid. Это не волнует и может быть источником ошибок программирования, если вы ожидаете, что там будет только Giraffe объектов.

List list = new List(); 
list.add("A");    // <-- Allowed 
list.add((Integer)10);  // <-- Also allowed, 
          // but now the list contains not only strings 
+0

Это очень ясно, но это не ответ на мой вопрос. – joost

0

В основном, ? в следующем

List<?> wildcardList = new ArrayList<TYPE>(); 

означает какой-то неизвестный (конкретный) тип. Таким образом, это не позволяет добавить что-то вроде String или Integer в список неизвестного типа, поскольку generics должен быть безопасным по типу.

В то время как в следующем

List<Object> listOfObject = new ArrayList<TYPE>(); 

вы можете добавить что-либо к нему, потому что все в Java Object. Так что это безопасно.

А также со следующими

List undefinedList = new ArrayList<TYPE>(); 

вы сообщаете компилятору, что вы не хотите использовать дженерики там. Это означает, что каждый метод, который вы вызываете на undefinedList, будет носить не общий характер, так как вы решили использовать необработанный List. Негенеративные версии всех контейнеров в структуре коллекции были написаны для работы в Object (какой-либо объект в Java).

+0

спасибо. Однако я не получаю разницу между raw и generic .. – joost

+0

'List ' (с '') является общим, а 'List' (с ** no **' ') является сырым. Это были версии, написанные до того, как дженерики были представлены на Java. –

+0

это означает, что они оба разные классы? Потому что: аргументов типа нет, какой тип будет использоваться? – joost

2

List undefinedList и List<?> wildcardList не то же самое, что и вы сами. Первый - это тип raw, а второй - неограниченный подстановочный знак.

Используйте неограниченный шаблон, если вы хотите использовать общий тип, но не знаете или не знаете, что такое фактический параметр типа. Вы не можете поместить в этот список ничего (кроме нулевого), и все, что вы знаете об элементе, из которого вы выходите, это то, что они расширяют Object (фактически List<?> - это то же самое, что и List<? extends Object>). Неограниченные маски полезны, потому что, если бы вы объявить что-то наивно, как List<Object>, вы не можете назначить, например List<String> к нему, в то время как вы можете назначить List<String> к List<?>

Вы не должны (почти) никогда не иметь необходимость использовать сырье типы, они доступны только для совместимости с кодом, написанным до Java 5.

1

Список означает, что это список неизвестного типа - как таковой вы не использовали бы его во время создания (как в вашем примере), вы обычно используйте его как параметр метода. Несвязанные подстановочные только очень полезны при использовании в качестве параметров методов, таких как:

public void printList(List<?> items) 

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

Если вы были следующие:

public void printList(List<Object> items) 

Тогда только список Object может быть переработаны - не список строк, Целые и т.д. Только объекты.

Посмотрите на Unbounded Wildcards - это объясняет его довольно хорошо

1

List<?> читается как список неизвестного типа. Как программист вы не можете делать какие-либо предположения о том, какой тип есть, и вы не можете помещать что-либо в такую ​​коллекцию, кроме нуля. Но вы можете быть уверены, что ваш список безопасен по типу, поскольку компилятор гарантирует безопасность типа для вас.

List в основном называется сырой тип. То есть он отказался от безопасности типа, гарантированного компилятором. Таким образом, вы можете поместить элементы любого типа в этот список, уничтожая его инварианты. Не используйте код с необработанными типами. Они в основном поддерживаются для обратной совместимости, потому что Java уже был во втором десятилетии разработки, когда Sun привнесла в таблицу обобщенные данные, и очень много кода было написано с использованием необработанных типов, и в противном случае эти программы нарушались.

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