Випуск с
List<String> list = new LinkedList();
це те, що в лівій частині ви використовуєте загальний тип, List<String>
де в правій частині ви використовуєте необроблений тип LinkedList
. Сировинні типи в Java фактично існують лише для сумісності з кодом попереднього генерику і ніколи не повинні використовуватися в новому коді, якщо ви абсолютно не повинні.
Тепер, якщо у Java були дженерики з самого початку і не було таких типів, як, наприклад LinkedList
, спочатку створені до того, як у них були дженерики, можливо, це могло б зробити так, що конструктор для загального типу автоматично виводить параметри свого типу зліва -ручна сторона завдання, якщо це можливо. Але це не відбулося, і він повинен по-різному ставитися до вихідних і загальних типів для зворотної сумісності. Це залишає для них необхідність зробити дещо інший , але не менш зручний спосіб декларування нового екземпляра родового об'єкта без необхідності повторювати його параметри типу ... оператор алмазу.
Що стосується вашого оригінального прикладу 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);
Однак алмазний оператор дозволяє правою частиною завдання визначити справжній загальний екземпляр з тими ж параметрами типу, що і лівий ... без необхідності вводити ці параметри знову. Це дозволяє зберегти безпеку дженериків майже з тими ж зусиллями, як і використання сировинного типу.
Я думаю, що головне, що потрібно зрозуміти, - це те, що сировинні типи (без <>
) не можна трактувати так само, як загальні типи. Коли ви декларуєте вихідний тип, ви не отримуєте жодної переваги та перевірки типу генеричних даних. Ви також повинні мати на увазі, що дженерики є частиною загальної мети мови Java ... вони не стосуються лише no-arg конструкторів Collection
s!