/ / Generación de instancias genéricas: nueva ArrayList <?> () Vs nueva ArrayList <Lista <? >> () [duplicado] - java, genéricos

Generación de instancias de genéricos: nueva ArrayList <?> () Frente a una nueva ArrayList <List <? >> () [duplicate] - java, generics

¿Por qué se permite esto?

List<List<?>> list = new ArrayList<List<?>>()

pero no esto?

List<?> list = new ArrayList<?>(); //Compile error: "Cannot instantiate the type ArrayList<?>"

Respuestas

3 para la respuesta № 1

Cuando crea un ArrayList, necesita definir el tipo de objetos que contendrá:

  • en el primer ejemplo, creará un ArrayList que contendrá Listas de tipos genéricos desconocidos, pero todos serán Listas.
  • en el segundo ejemplo, intenta crear un ArrayList de tipo desconocido, que no está permitido.

1 para la respuesta № 2

No puede crear una instancia de un objeto con un genérico desconocido, razón por la cual la segunda línea falla.

List<?> list = new ArrayList<String>();

Sin embargo, al utilizar la "lista" funcionaría, el código no sabría que era una lista de cadenas, lo que la hacía bastante inútil.

La primera invocación funciona porque usted especificaSi desea crear una lista de arrays de otras listas, se determinará lo que esas listas se determinarán cuando realmente ejemplifique las listas secundarias. Aquí solo se crea una instancia de la lista principal, que es efectivamente una lista de listas.


0 para la respuesta № 3

Piense en una definición de tipo genérico como ambas

  1. La definición de algún tipo de constructor para poder crear una nueva "instancia de tipo" no genérica de un tipo genérico.
  2. Una definición de tipo.

Ahora vamos a traducir esta lógica a variables no genéricas:

CharSequence val = new String("foo");

es perfectamente legal La variable val está representando un tipo (2) y, por supuesto, nunca habrá instancias directas de la interfaz CharSequence. Sin embargo, usted podría no construir (1) este tipo, pero puede asignarle un subtipo asignable, como un String. No se puede reemplazar la creación de una cadena diciendo algo como new [? extends CharSequence], necesita nombrar explícitamente el tipo que se construirá.

Ahora regresemos a los genéricos donde las cosas son similares. Cuando llama a un constructor de un tipo genérico.

new ArrayList<List<?>>()

de alguna manera estás construyendo (2) una nueva "instancia de tipo" de un tipo genérico donde necesita asignar explícitamente un valor a la variable de tipo T de la definición genérica en ArrayList<T>. ? por sí solo no describe un tipo de Java y, por lo tanto, no puede utilizarse como un valor de asignación. Sin embargo, aparte de T = ?, la definición T = List<?> es posible ya que el comodín puede ser parte de una definición de tipo Java válida.

Cuando se utiliza el comodín en una definición de tipo (1) como en

List<?> list

usted no construyendo un nuevo tipo genérico, simplemente estás describiendo los límites de uno. Por lo tanto, el comodín se puede utilizar en esta ocasión.