Wednesday, February 4, 2009

Collection.addAll в Java Generics

Родовые типы (generics) в Java - одна из самых интересных и полезных возможностей. Она очень грамотно и логично спроектирована, но иногда попадаются моменты, которые ставят в тупик. Лично я пару натыкался на такой фрагмент:
List<? extends MyType> l1; List<? extends MyType> l2; l1.addAll(l2); Компилятор при этом выдает ошибку в строке, где элементы одной коллекции добавляются в другую. Казалось бы, в чем проблема - коллекции типизированы одинаково, следовательно, могут содержать одинаковые элементы. На самом деле, если бы такой код был допустимым, нарушалась бы безопасность типов (в коллекцию можно было бы добавить недопустимые элементы). Это демонстрирует следующий пример:
List<Double> dl = null; List<Integer> il = null; List<? extends Number> l1 = dl; List<? extends Number> l2 = il; l1.addAll(l2); В коллекцию Double попадают объекты типа Integer.