2016-07-15 102 views
5

1) OKPerché lista <Integer[]> listOfArrays = Arrays.asList (new Integer [] {1, 2}) non viene compilato?

List<int[]> listOfArrays1 = Arrays.asList(new int[]{1, 2}); 

2) OK

List<int[]> listOfArrays2 = Arrays.asList(new int[]{1, 2}, new int[]{3, 4}); 

3) Errore di compilazione Type mismatch: cannot convert from List<Integer> to List<Integer[]>

List<Integer[]> listOfArrays3 = Arrays.asList(new Integer[]{1, 2}); 

4) OK

List<Integer[]> listOfArrays4 = Arrays.asList(new Integer[]{1, 2}, new Integer[]{3, 4}); 

Questa è la firma per asList: public static <T> List<T> asList(T... a)

asList aspetta 0 o più "a" di tipo T. La mia "a" è new Integer[]{1, 2} ed è di tipo Integer[]. Quindi, perché genera uno List<Integer> invece di uno List<Integer[]>? sguardo

+0

Si prega di spiegare come 1 e 2 non hanno mostrato alcun errore. 'List' non funziona con' int' primitivo. – Sufian

+2

@Sufian 'int []' non è primitivo. È un oggetto. – Gendarme

+0

(1) risolve correttamente è perché 'T' può essere' int [] 'ma non' int'. Http://stackoverflow.com/questions/2721546/why-dont-java-generics-support-primitive-types – blgt

risposta

3

Let l'esempio problema (3 °):

List<Integer[]> listOfArrays3 = Arrays.asList(new Integer[]{1, 2}); 

Come mostrato, la firma del metodo è:

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

In questo caso particolare, il singolo Integer[] viene presa in considerazione per il T.... Un array o un numero non specificato dello stesso oggetto può essere fornito a T.... Poiché hai specificato un array, lo T è considerato come Integer (e T... diventa Integer[]).

Quando si fornisce un int[] come un unico argomento (1 °), il compilatore non avvolgere automaticamente l'accaduto a un Integer[] perché un tale oggetto è diverso da un int[]. Poiché int non è un oggetto, l'unico tipo di oggetto che può adattarsi a T è int[] (che crea il parametro come int[][]).

Fornendo due int[] s (2a) è molto più evidente, come il compilatore può considerare soltanto due array per T... come int[] s, quindi T... è anche int[][].

Quando si fornisce due Integer[] s (4 °), è più evidente ancora una volta che il compilatore non ha altra scelta, ma di considerare i due parametri che compongono T... come Integer[] (che diventa un singolo array: Integer[][]).

Edit: Fornire un array come vararg:

È possibile fornire un singolo array come vararg.Facciamo un esempio, senza un generico:

public int iLoveMeSomeInts(int...nums) 

Fornire un int[] a questo metodo come argomento funziona. L'array è considerato come un vararg di int s ai fini della convalida della firma, quindi il vararg è considerato come uno int[] per la logica interna del metodo.

La differenza nell'esempio è che l'argomento è T.... Un generico deve essere un oggetto, pertanto il compilatore non può considerare uno int[] come un vararg di int... in questo caso. Il compilatore non ha altra scelta che considerare lo int[] come un singolo elemento in un vararg di int[]... (perché int[] è un oggetto). Non c'è ambiguità in questo.

Tuttavia, poiché Integerè un oggetto, il compilatore utilizzare un unico Integer[] come Integer....

La cosa più bella è questa: se si voleva un Integer[] restituito utilizzando il metodo in questione, e ancora fornito un solo Integer[], si potrebbe chiamare:

Arrays.<Integer[]>asList(new Integer[] {1, 2}); 

questo forza il compilatore a considerare il vostro singolo Integer[] come Integer[]....

+0

Immagino che non sapessi davvero come funzionano i vararg. – Gustavo

+0

varvargs sono grandiosi, perché è possibile fornire qualsiasi numero dello stesso oggetto e nel metodo stesso tale argomento viene trattato come una matrice. Il risultato è che un generico 'T' deve essere un oggetto, quindi fornire un' int [] 'non conterà come un vararg di' int's. – Zircon

+0

Quindi in altre parole (se ho capito bene), il caso 3 è ambiguo perché può essere interpretato come entrambi i due argomenti '(1, 2)' e un argomento '(nuovo Intero [] {1,2})'. Accade che il compilatore decida di scegliere il primo e se si aspetta il secondo risultato, si rimane sorpresi. – Gendarme