2013-12-24 3 views
3

Не могли бы вы объяснить мне, что здесь происходит и почему это работает без ошибок.Java generics understanding

List list = new ArrayList<String>(); 
list.add(1); 

Я извиняюсь, если уже были подобные вопросы, я не смог правильно сформулировать вопрос так не могу Google это

+2

У вас есть предупреждения о компиляторе? – shoover

ответ

4

Что здесь происходит, раскрывает слабость стирания типа, механизм, лежащий в основе дженериков Java. Реализация массива ArrayList не изменяется при изменении параметра родового типа: это всегда java.lang.Object за сценой.

Поскольку вы не указали параметр типа в интерфейсе при объявлении своего списка, компилятор позволяет добавлять объекты любого типа, а не только строки. В частности, int получает autoboxed в java.lang.Integer, поэтому значение 1 может быть добавлено в ваш список.

+0

Итак, ничего не зависит от параметра типа ArrayList? Используется только параметр списка? – Patison

+0

@MaxVasileusky Правильно, так как тип стирается после времени компиляции и потому, что тип переменной не зависит от того, что вы ее назначили, имеет значение только общий параметр интерфейса List в декларации. – dasblinkenlight

1

воспроизведенных ссылка важна. Таким образом,

List list = new ArrayList<String>(); 

не имеет смысла. Он должен быть

List<String> list = new ArrayList<String>(); 

Если вы не не предоставлять в дженериков для ссылочного типа (не фактический тип объекта) он берется в качестве Object. Поэтому вы можете добавить что-нибудь к нему.

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

2

Использование raw typeList list приблизительно эквивалентно использованию List<Object> без проверки типа. Этот тип List примет любой тип объекта. Заявление

list.add(1); 

autoboxes в Integer добавить к List

+0

Это связано с универсальной инвариантностью, взгляните на этот [фрагмент] (http://ideone.com/C1AkJ7) – Reimeus

+0

Список неизвестных ('?') Не позволяет добавлять (кроме 'null'). – Reimeus

+0

Фактически Список l даже не эквивалентен списку . Я перепутал эту концепцию. Апология. –

0

Sure. если вы знакомы с C++, дженерики похожи на шаблоны (с небольшим исключением, но не позволяют выкопать эту деталь). Основная идея Generics - это безопасность типов в вашем коде и, следовательно, ясность. Это отлично подходит для статических типизированных языков, таких как Java. Список - это интерфейс, и Arraylist простирается от него. Следовательно, его родительский (суперкласс) является List. Список имеет такие функции, как подсписок и т. Д.

list.add (1) просто вызывает метод добавления интерфейса списка (который переопределяется в Arraylist), чтобы добавить этот элемент в массив.

использовать также:

List<String> list = new ArrayList<String> 

большую статью о воспроизведенных здесь: http://docs.oracle.com/javase/tutorial/java/generics/

1
Could you please explain me what happens here and why it works without errors. 

Type erasure.

Java генерики существуют только во время компиляции. Если вы попытаетесь вставить int во что-то, что объявлено только как List (которое по умолчанию привязано к Object) по умолчанию, оно будет работать нормально.