2016-07-15 9 views
5

1) OKWarum Liste <Integer[]> listOfArrays = Arrays.asList (new Integer [] {1, 2}) kompiliert nicht?

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) Kompilierfehler 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}); 

Dies ist die Unterschrift für asList: public static <T> List<T> asList(T... a)

asList erwartet 0 oder mehr "a" des Typs T. Mein "a" new Integer[]{1, 2} ist, und es ist vom Typ Integer[]. Also, warum erzeugt es eine List<Integer> anstelle einer List<Integer[]>?

+0

Bitte erläutern Sie, wie 1 und 2 keinen Fehler zeigten. 'List' arbeitet nicht mit dem Primitiv' int'. – Sufian

+2

@Sufian 'int []' ist nicht primitiv. Es ist ein Objekt. – Gendarme

+0

(1) wird korrekt aufgelöst, weil 'T'' int [] 'sein kann, aber nicht' int'. Related http://stackoverflow.com/questions/2721546/why-dont-java-generics-support-primitive-types – blgt

Antwort

3

Blick Lassen Sie uns auf das Problem Beispiel (3.):

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

Wie Sie zeigte, die Methodensignatur ist:

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

In diesem speziellen Fall ist die einzige Integer[] wird erwogen für die T.... Ein Array oder eine nicht spezifizierte Nummer des gleichen Objekts kann an T... geliefert werden. Da Sie ein Array angegeben haben, wird T als Integer (und T... wird Integer[]) betrachtet.

Wenn Sie eine int[] als ein einziges Argument (1) liefern, wird der Compiler nicht automatisch umbrochen dies einem Integer[] weil ein solches Objekt aus einem int[] unterscheidet. Da int kein Objekt ist, ist der einzige Objekttyp, der in T passen kann, int[] (der den Parameter als int[][] erstellt).

Versorgung zwei int[] s (2.) ist viel offensichtlicher, da der Compiler nur zwei Arrays für T... als int[] s betrachten kann, so T... ist auch int[][].

Wenn Sie zwei Integer[] s (4.) liefern, ist es offensichtlich wieder, dass der Compiler keine andere Wahl hat, aber die beiden Parameter zu betrachten, die T... als Integer[] bilden (die ein einzelnes Array wird: Integer[][]).

Edit: ein Array als Vararg Versorgung:

Sie können liefern ein einzelnes Array als Vararg.Nehmen wir ein Beispiel nehmen ohne generic:

public int iLoveMeSomeInts(int...nums) 

eine int[] dieser Methode Versorgung als Argument funktioniert. Das Array wird als ein Vararg von ints für die Zwecke der Validierung der Signatur angesehen, dann wird das Vararg als int[] für die interne Logik des Verfahrens angesehen. Der Unterschied in Ihrem Beispiel ist, dass das Argument T... ist. Ein generischer Tmuss ein Objekt sein, so dass der Compiler int[] in diesem Fall nicht als Vararg von int... betrachten kann. Der Compiler hat dann keine andere Wahl, als die int[] als einzelnes Element in einem Vararg von int[]... zu betrachten (weil int[] ein Objekt ist). Darin besteht keine Zweideutigkeit.

Da jedoch Integer ein Objekt ist, wird der Compiler einen einzigen Integer[] als Integer... verwenden.

Was ist noch cooler ist: Wenn Sie ein Integer[] zurückgegeben mit der Methode in Frage, und nach wie vor nur geliefert, ein einziges Integer[] wollten könnte man nennen:

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

Dies zwingt den Compiler Ihre einzigen Integer[] zu betrachten als Integer[]....

+0

Ich glaube, ich wusste nicht wirklich, wie Varargs funktionieren. – Gustavo

+0

varvargs sind großartig, weil Sie eine beliebige Anzahl des gleichen Objekts liefern können, und in der Methode selbst wird dieses Argument als Array behandelt. Der Fehler dabei ist, dass ein generisches 'T' ein Objekt sein muss, also wird das Liefern eines' int [] 'nicht als Vararg von' int' gezählt. – Zircon

+0

Mit anderen Worten (wenn ich das richtig verstanden habe), ist Fall 3 mehrdeutig, weil es sowohl als zwei Argumente '(1, 2)' als auch als ein Argument '(new Integer [] {1,2}) interpretiert werden kann. Es kommt vor, dass der Compiler entscheidet, den ersten zu wählen, und wenn Sie das zweite Ergebnis erwarten, werden Sie überrascht. – Gendarme

Verwandte Themen