El problema con
List<String> list = new LinkedList();
es que en el lado izquierdo, está utilizando el tipo genérico, mientras List<String>
que en el lado derecho está utilizando el tipo sin formato LinkedList
. Los tipos sin formato en Java efectivamente solo existen para la compatibilidad con el código pre-genérico y nunca deben usarse en código nuevo a menos que sea absolutamente necesario.
Ahora, si Java tenía genéricos desde el principio y no tenía tipos, como los LinkedList
que se crearon originalmente antes de tener genéricos, probablemente podría haberlo hecho para que el constructor de un tipo genérico infiera automáticamente sus parámetros de tipo desde la izquierda lado de la tarea, si es posible. Pero no lo hizo, y debe tratar los tipos sin procesar y los tipos genéricos de manera diferente para la compatibilidad con versiones anteriores. Eso hace que tengan que hacer una forma ligeramente diferente , pero igualmente conveniente, de declarar una nueva instancia de un objeto genérico sin tener que repetir sus parámetros de tipo ... el operador de diamante.
En cuanto a su ejemplo original de List<String> list = new LinkedList()
, el compilador genera una advertencia para esa asignación porque debe hacerlo. Considera esto:
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);
Existen genéricos para proporcionar protección en tiempo de compilación contra hacer lo incorrecto. En el ejemplo anterior, el uso del tipo sin formato significa que no obtiene esta protección y obtendrá un error en tiempo de ejecución. Es por eso que no debes usar tipos sin procesar.
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
Sin embargo, el operador de diamante permite que el lado derecho de la asignación se defina como una instancia genérica verdadera con los mismos parámetros de tipo que el lado izquierdo ... sin tener que volver a escribir esos parámetros. Le permite mantener la seguridad de los genéricos con casi el mismo esfuerzo que usar el tipo sin procesar.
Creo que la clave para entender es que los tipos sin formato (sin <>
) no pueden tratarse de la misma manera que los tipos genéricos. Cuando declara un tipo sin procesar, no obtiene ninguno de los beneficios y la verificación de tipos de genéricos. También debe tener en cuenta que los genéricos son una parte de propósito general del lenguaje Java ... ¡no solo se aplican a los constructores sin argumentos de Collection
s!