java - metodos - Crear nuevo objeto genérico con comodín
objeto t en java (2)
Por favor, explique este error de tiempo de compilación de comodines de código genérico:
//no compile time error.
List<? extends Number> x = new ArrayList<>();
//compile time error.
List<? extends Number> x = new ArrayList<? extends Number>();
Utilizar
List<? extends Number> x = new ArrayList<Number>();
en lugar.
No es válida la sintaxis para instanciar un tipo genérico con comodines. El tipo List<? extends Number>
List<? extends Number>
significa una List
de algún tipo que es o se extiende Number
. Crear una instancia de este tipo no tiene sentido, porque con la instanciación estás creando algo específico:
new ArrayList<? extends Number>();//compiler:"Wait, what am I creating exactly?"
Los tipos genéricos con comodines solo tienen sentido para las variables y los parámetros del método, porque esto permite una mayor libertad en lo que se les puede asignar / pasar.
//compiler:"Okay, so passing in a List<Integer> or a List<Double> are both fine"
public void eatSomeNumbers(List<? extends Number> numbers) {
for (Number number : numbers) {
System.out.println("om nom " + number + " nom");
}
}
Asegúrese de tener en cuenta las limitaciones que conlleva el uso de comodines.
List<? extends Number> numList = ...
numList.add(new Integer(3));//compiler:"Nope, cause that might be a List<Double>"
En cuanto a su primer ejemplo, el diamante es una nueva característica en Java 7 que permite al compilador inferir el tipo de la nueva instancia genérica, en función del tipo de la variable a la que está asignado. En este caso:
List<? extends Number> x = new ArrayList<>();
El compilador es más probable que infiera una new ArrayList<Number>()
aquí, pero lo que se infiere apenas importa, siempre que sea una asignación válida para la variable dada. Esta fue la razón por la que se introdujo el operador de diamante: la especificación del tipo genérico de un nuevo objeto era redundante, siempre que algún tipo genérico lo convirtiera en una asignación / argumento válido.
Este razonamiento solo tiene sentido si recuerda que los genéricos en Java son una característica del lenguaje puramente en tiempo de compilación, debido a la supresión del tipo , y no tienen ningún significado en el tiempo de ejecución. Los comodines existen solo debido a esta limitación. Por el contrario, en C # la información de tipo genérico se queda en el tiempo de ejecución, y los comodines genéricos no existen en ese idioma.