Dado este ejemplo de los genéricos tutorial.

List<String> list = new ArrayList<>();
list.add("A");

//The following statement should fail since addAll expects
//Collection<? extends String>

list.addAll(new ArrayList<>());

¿Por qué la última línea no compilar, cuando parece que debe compilar. La primera línea se utiliza una muy similar construir y compila sin problema.

Por favor explique detalladamente.

«¿Por qué no lo siguiente no funciona?» es un poco débil. ¿Qué es exactamente lo que usted espera? Y ¿cuál es el mensaje de error? Hay muchas razones «no funciona». Usted debe ser más preciso en la pregunta para obtener respuestas precisas.
download.oracle.com/javase/tutorial/java/generics/index.html volver cuando usted ha leído y se absorbe.
En realidad, a partir de Java 7 esto debería funcionar – diamond operator, la votación para abrir, demasiado.
Pradeep, que están utilizando Java 7? Que es un prerequisito para que compile.
si usted está no el uso de Java 7, a continuación, que es la razón por la que el código no compila: El tutorial está dirigido a Java 7. no Obstante el código específico que usted cita no incluso compilar en Java 7 (por otras razones).

OriginalEl autor Pradeep Kumar | 2011-09-26

3 Comentarios

  1. 14

    Primera de todas: a menos que usted está usando Java 7 todo esto no va a funcionar, porque el diamante <> sólo ha sido introducido en que versión de Java.

    También, esta respuesta se supone que el lector entiende los conceptos básicos de los medicamentos genéricos. Si no, entonces, leer las otras partes del tutorial y volver cuando usted entiende los.

    El diamante es en realidad un acceso directo para no tener que repetir el tipo genérico de la información cuando el compilador podría averiguar el tipo en su propio.

    El más común de los casos de uso es cuando se define una variable en la misma línea se inicializa:

    List<String> list = new ArrayList<>(); //is a shortcut for
    List<String> list = new ArrayList<String>();

    En este ejemplo, la diferencia no es importante, pero una vez llegas a Map<String, ThreadLocal<Collection<Map<String,String>>>> que va a ser un principales de mejora (nota: yo no fomentar realmente el uso de tales construcciones!).

    El problema es que las reglas sólo ir tan lejos. En el ejemplo de arriba, es bastante obvio que lo que debería ser y el compilador y el desarrollador de acuerdo.

    En esta línea:

    list.addAll(new ArrayList<>());

    se parece a ser evidente. Al menos el desarrollador sabe que el tipo debe ser String.

    Sin embargo, buscando en la definición de Colección.addAll() vemos el tipo de parámetro a ser Collection<? extends E>.

    Significa que addAll acepta cualquier colección que contiene objetos de cualquier tipo desconocido que se extiende el tipo de nuestra list. Eso es bueno porque significa que usted puede addAll un List<Integer> a un List<Number>, pero hace que nuestro tipo de inferencia más complicado.

    De hecho, hace que la inferencia de tipo no trabajar dentro de las normas que actualmente establecidos por el JLS. En algunos situaciones se podría argumentar que las reglas podría ser extendido para trabajar, pero las reglas actuales implica que no lo haga.

    por las respuestas

    OriginalEl autor Joachim Sauer

  2. 1

    La explicación de la La Inferencia De Tipos documentación parece responder a esta pregunta directamente ( a menos que me estoy perdiendo algo más ).

    Java SE 7 y versiones posteriores admiten limitada inferencia de tipos genéricos de la creación de la instancia; sólo puede utilizar la inferencia de tipos, si el tipo en parámetros del constructor es obvio por el contexto. Por ejemplo, el siguiente ejemplo no compila:

    List<String> list = new ArrayList<>();
    list.add("A");
    
      //The following statement should fail since addAll expects
      //Collection<? extends String>
    
    list.addAll(new ArrayList<>());

    Nota de que el diamante trabaja a menudo en las llamadas de método; sin embargo, para mayor claridad, se sugiere que utilice el diamante principalmente para inicializar una variable donde se declara.

    En comparación, el ejemplo siguiente se compila:

    //The following statements compile:
    
    List<? extends String> list2 = new ArrayList<>();
    list.addAll(list2);
    El tutorial realmente no se explica porque el diamante no funciona aquí. Sólo de la mano-ondas y dice que «a menudo las obras».
    para molestarte.Yo dint entender .Se puede explicar con simples palabras.Lo siento de nuevo
    De acuerdo. Tal vez el JLS dice algo.
    Hmm.. me parece obvio. Se establece claramente que addAll espera de la Colección de<? se extiende E> que no se puede hacer, ya que podría ser un tipo desconocido de ampliar el tipo definido de la lista y, por tanto, la inferencia no funciona.
    se puede argumentar que, en este caso puede simplemente inferir el tipo String que sería correcta de acuerdo al tipo de sistema y que iba a permitir correctamente la llamada. En mi opinión eso es suficiente. Parece ser una restricción similar a la antigua «¿por Qué no creación de instancias de objeto utilizar las mismas reglas de inferencia que se utilizan en el método de invocación?» en Java 5 y Java 6 (siendo cierto en Java 7).

    OriginalEl autor Kal

  3. 0

    Al compilar una invocación de método, javac necesita saber el tipo de los argumentos en primer lugar, antes de determinar que método de firma coincida con ellos. Así que el método de tipo de parámetro no se conoce antes de que el tipo de argumento es conocido.

    Tal vez esto puede ser mejorada, a partir de hoy, el tipo de argumento es independiente del contexto.

    OriginalEl autor irreputable

Dejar respuesta

Please enter your comment!
Please enter your name here