2011-04-16 6 views
70

El siguiente código (ejecutar en Android) siempre me da una ClassCastException en la 3ª línea:java: (String []) List.toArray() da ClassCastException

final String[] v1 = i18nCategory.translation.get(id); 
final ArrayList<String> v2 = new ArrayList<String>(Arrays.asList(v1)); 
String[] v3 = (String[])v2.toArray(); 

También sucede cuando v2 es objeto [ 0] y también cuando hay cadenas en él. ¿Alguna idea de por qué?

+0

Es posible que desee leer sobre Covarianza y contravarianza - http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29#Java – Hut8

+0

Qué pasa con el caso en el que T es una interfaz con un método de fábrica para creación de instancias. – sebaj

+2

@LaceCard: esto solo está relacionado muy indirectamente con la covarianza/contravarianza. El verdadero problema es que esto es una consecuencia directa del comportamiento especificado del método 'toArray()'. –

Respuesta

188

Esto se debe a que cuando se utiliza

toArray() 

devuelve un Object [], que no puede ser forzada a String [] (incluso aunque los contenidos son cadenas) Esto se debe a que el método sólo se toArray para crear una

List 

y no

List<String> 

como genéricos son un código fuente único, y no está disponible en tiempo de ejecución de una nd por lo que no puede determinar qué tipo de matriz crear.

uso

toArray(new String[v2.size()]); 

que asigna el tipo de array (String [] y del tamaño adecuado)

+0

+1 aunque no explica por qué. – corsiKa

+1

@glowcoder - agregó un intento de explicación – MeBigFatGuy

+2

cuz genéricos, por eso –

28

Está utilizando el mal toArray()

Recuerde que los genéricos de Java son en su mayoría sintáctica azúcar. Una ArrayList en realidad no sabe que todos sus elementos son cadenas.

Para solucionar su problema, llame al toArray(T[]). En su caso,

String[] v3 = v2.toArray(new String[v2.size()]); 

Tenga en cuenta que la forma genericized toArray(T[]) vuelve T[], por lo que el resultado no tiene por qué ser echado de forma explícita.

-1

La solución anterior no funciona para mí. Un mejor ejemplo es:

Person[] men = people.stream() 
      .filter(p -> p.getGender() == MALE) 
    .toArray(Person[]::new);