2011-01-25 24 views
16

La gente dice que el método asList convierte la matriz en una lista y no está copiando, por lo que cada cambio en 'aList' se reflejará en 'a'. Por lo tanto, agregar valores nuevos en 'aList' es ilegal, ya que la matriz tiene un tamaño fijo.Arrays.asList() ¿duda?

Pero, el método asList() devuelve ArrayList<T>. Cómo el compilador diferencia la línea 3 de 5. La línea 3 me da una excepción (UnsupportedOperationException).

 String[] a = {"a","b","c","d"};//1 
     List<String> aList = Arrays.asList(a);//2 
     aList.add("e");//3 
     List<String> b = new ArrayList<String>();//4 
     b.add("a");//5 
+5

No importa lo que diga la gente. Importa lo que diga * Javadoc *. – EJP

Respuesta

3

Es una excepción y no es un error del compilador. Se lanza cuando se ejecuta el programa y no en el tiempo de compilación. Básicamente, la clase real que devolverá Arrays.asList tiene un throw UnsupporteOperationException dentro del método add().

Para ser más específicos Arrays.asList volverá una clase interna definida dentro de la clase Arrays que se deriva de AbstractList y no implementa el método add. El método add del AbstractList arroja la excepción.

33

Esta implementación de Lista que recibe de Arrays.asList es una vista especial de la matriz; no puede cambiar su tamaño.

El tipo de devolución de Arrays.asList() es java.util.Arrays.ArrayList que a menudo se confunde con java.util.ArrayList. Arrays.ArrayList simplemente muestra la matriz como una lista.

+3

+1 Creo que esto es básicamente el quid de la cuestión. El OP ve que el tipo de devolución es ArrayList, y se pregunta por qué se comporta de forma diferente a una ArrayList. Pregunta perfectamente válida. –

+0

Andreas_D, el tipo de retorno de 'Arrays.asList (...)' es 'java.util.List' y no' java.util.Arrays.ArrayList'. –

3

Suponiendo que Arrays.asList() devuelve ArrayList, pero ese no es el caso. Arrays.asList() devuelve una implementación no especificada de List. Esa implementación simplemente arroja un UnsupportedOperationException en cada método no compatible.

4

asList() no devuelve un java.util.ArrayList, devuelve un java.util.Arrays$ArrayList. Esta clase ni siquiera se extiende a java.util.ArrayList, por lo que su comportamiento puede ser (y es) completamente diferente.

El método add() se hereda de java.util.AbstractList, que de forma predeterminada arroja UnsupportedOperationException.

+0

No, asList devuelve una lista. Lo que está describiendo puede ser cierto para una implementación Java específica, pero no es algo en lo que pueda confiar. – jarnbjo

+0

@jarnbjo: esto es cierto tanto para Sun Java como para GNU Classpath y probablemente para cualquier otra implementación, ya que es la forma más sencilla de hacerlo. Como la pregunta era sobre cómo el compilador puede decir, pensé que un ejemplo concreto sería más fácil de entender. – OrangeDog

0

asList devuelve una lista de tamaño fijo, por lo que no puede agregarle nuevos elementos. Como la lista que devuelve es realmente una "vista" de la matriz de la que se creó ('a' en su caso), tiene sentido que no podrá agregar elementos, al igual que no puede agregar elementos a una matriz. Consulte la documentación de asList

9

Read again, el tipo de Arrays.asList es:

public static <T> List<T> asList(T... a) 

que establece claramente que asList devuelve un objeto que implementa la interfaz java.util.List, en ninguna parte se dice que devolverá una instancia de clase java.util.ArrayList.

A continuación, observe que la documentación sobre List.add dice:

complemento booleano (E e)

          añade el elemento especificado al final de esta lista (operación opcional).

Técnicamente, cada vez que se utiliza una variable de tipo lista (en lugar de ArrayList), siempre debe tener cuidado de esperar que este método puede lanzar UnsupportedOperationException. Si está seguro de que solo recibirá una implementación de la Lista que siempre tenga la semántica correcta de .add(), puede omitir la comprobación a riesgo de un error cuando se invalide su suposición.

1

La clave para esto es la aplicación List devuelto por

List<String> aList = Arrays.asList(a); 

Si nos fijamos en el código fuente en Arrays verá que contiene una clase estática privada interna ArrayList. Esto no es lo mismo que java.util.ArrayList.

5

Manoj,

el tipo de retorno de Arrays.List alguna aplicación interna desconocido de la interfaz de lista y no java.util.ArrayList, por lo que puede asignar sólo a un tipo de lista.

Si asigna a un ArrayList, por ejemplo, que le dará tiempo de compilación de error "No coinciden los tipos: no se puede convertir de la lista de ArrayList"

ArrayList<String> aList = Arrays.asList(a);// gives Compile time error 

Desde el Javadoc "Arrays.asList Devuelve un fijo lista de tamaño respaldada por la matriz especificada. (Los cambios en la lista devuelta "escritura" en la matriz.) "eso significa que solo se le proporciona una vista de lista de la matriz que se crea IMO en tiempo de ejecución y, por supuesto, no puede cambiar el tamaño de una matriz por lo que no puede cambiar el tamaño de "Arrays.asList" también.

OMI la implementación interna de Arrays.asList tiene todos los métodos implementados que pueden cambiar el tamaño de la matriz como -

void add(E e) 
{ 
//some unknown code 
throw(java.lang.UnsupportedOperationException); 
} 

lo que cada vez se intenta alterar el tamaño de la matriz que arroja el UnsupportedOperationException.

Aún si desea agregar algunos elementos nuevos a una ArrayList utilizando dicha sintaxis, puede hacerlo creando una subclase de Arraylist (preferiblemente utilizando la subclase anónima de ArrayList). Puede pasar el tipo de retorno de Arrays.List al constructor de ArrayList, algo como esto (es decir, pública ArrayList (Collection c).) -

List<String> girlFriends = new java.util.ArrayList<String>(Arrays.asList("Rose", "Leena", "Kim", "Tina")); 
girlFriends.add("Sarah"); 

Ahora puede agregar fácilmente a Sarah a su lista de GF utilizando el mismo sintaxis.

PD - Seleccione esta u otra como respuesta porque todo ha sido explicado. Su baja tasa de aceptación es muy desalentadora.

Cuestiones relacionadas