Вопрос с
List<String> list = new LinkedList();
в том, что с левой стороны вы используете универсальный тип, а List<String>
с правой стороны вы используете необработанный тип 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!