Проблема с
List<String> list = new LinkedList();
заключается в том, что с левой стороны вы используете универсальный тип List<String>
, а с правой стороны вы используете raw type LinkedList
.Необработанные типы в Java эффективно существуют только для совместимости с пре-родовым кодом и никогда не должны использоваться в новом коде, если только вам это не нужно.
Теперь, если у Java были дженерики с самого начала и не было типов,такие как LinkedList
, которые были изначально созданы до того, как у него были универсальные шаблоны, возможно, он мог бы сделать это так, чтобы конструктор универсального типа автоматически выводил параметры своего типа из левой части присваивания, если это возможно.Но это не так, и он должен обрабатывать необработанные типы и универсальные типы по-разному для обратной совместимости.Это оставляет им необходимость создавать немного другой , но одинаково удобный способ объявления нового экземпляра универсального объекта без необходимости повторять параметры его типа ... оператор diamond.
Что касается вашего исходного примера List<String> list = new LinkedList()
, компилятор генерирует предупреждение для этого назначения, потому что это должно.Подумайте об этом:
List<String> strings = ... // some list that contains some strings
// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);
Обобщения существуют для обеспечения защиты во время компиляции от неправильных действий.В приведенном выше примере использование необработанного типа означает, что вы не получите эту защиту и получите ошибку во время выполнения.Вот почему вы не должны использовать необработанные типы.
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
Оператор diamond, однако, позволяет определять правую часть назначения как истинный универсальный экземпляр с теми же параметрами типа, что и с левой стороной.... без необходимости вводить эти параметры снова.Это позволяет вам сохранить безопасность обобщенных типов при почти таких же усилиях, что и при использовании необработанного типа.
Я думаю, что ключевым моментом для понимания является то, что исходные типы (без <>
)нельзя рассматривать так же, как универсальные типы.Когда вы объявляете необработанный тип, вы не получаете ни одного из преимуществ и проверки типа обобщений.Вы также должны иметь в виду, что универсальные элементы являются частью общего назначения языка Java ... они не просто применяются к конструкторам без аргументов Collection
s!