O problema com
List<String> list = new LinkedList();
é que, no lado esquerdo, você está usando o tipo genérico, eList<String>
no lado direito, o tipo brutoLinkedList
. Os tipos brutos em Java efetivamente existem apenas para compatibilidade com código pré-genérico e nunca devem ser usados em novo código, a menos que você precise.
Agora, se Java tivesse genéricos desde o início e não tivesse tipos, como LinkedList
, originalmente criados antes de ter genéricos, provavelmente poderia ter feito isso para que o construtor de um tipo genérico deduza automaticamente seus parâmetros de tipo da esquerda lado da tarefa, se possível. Mas não funcionou, e deve tratar os tipos brutos e genéricos de maneira diferente para compatibilidade com versões anteriores. Isso faz com que eles precisem criar uma maneira um pouco diferente , mas igualmente conveniente, de declarar uma nova instância de um objeto genérico sem precisar repetir seus parâmetros de tipo ... o operador diamante.
Quanto ao seu exemplo original List<String> list = new LinkedList()
, o compilador gera um aviso para essa atribuição porque deve. Considere isto:
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);
Existem genéricos para fornecer proteção em tempo de compilação contra fazer a coisa errada. No exemplo acima, usar o tipo bruto significa que você não recebe essa proteção e receberá um erro no tempo de execução. É por isso que você não deve usar tipos brutos.
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
O operador de diamante, no entanto, permite que o lado direito da atribuição seja definido como uma instância genérica verdadeira com os mesmos parâmetros de tipo que o lado esquerdo ... sem precisar digitar esses parâmetros novamente. Permite manter a segurança dos genéricos com quase o mesmo esforço que o uso do tipo bruto.
Acho que o principal é entender que tipos brutos (sem <>
) não podem ser tratados da mesma forma que tipos genéricos. Ao declarar um tipo bruto, você não obtém nenhum dos benefícios e a verificação de tipo de genéricos. Você também deve ter em mente que os genéricos são uma parte de uso geral da linguagem Java ... eles não se aplicam apenas aos construtores sem argumento de Collection
s!