tutorial - Warum Java nicht autobox int
scala tutorial pdf (4)
Wenn ich folgendes mache,
-
arrayList1
- enthält ein Element und es ist einint[]
. -
arrayList2
- nicht kompilierend (Fehler: Der KonstruktorArrayList<Integer>(List<int[]>)
ist nicht definiert) -
arrayList3
- enthält 7 Elemente und sie sindInteger
Objekte
Hier ist der Code:
int[] intArray = new int[]{2,3,4,5,6,7,8};
ArrayList arrayList1 = new ArrayList(Arrays.asList(intArray));
ArrayList<Integer> arrayList2 = new ArrayList<Integer>(Arrays.asList(intArray));
Integer[] integerArray = new Integer[]{2,3,4,5,6,7,8};
ArrayList<Integer> arrayList3 = new ArrayList<Integer>(Arrays.asList(integerArray));
Frage: Warum schreibt der Compiler die Elemente im int[]
in Integer
und erzeugt eine ArrayList<Integer>
? Was ist der Grund dafür? Ist das meine Dummheit oder ein anderer Grund?
Der Unterschied ist, int[]
selbst ein Object
, während Integer[]
ein Array von Referenzen auf ein Integer
Objekt ist.
Arrays.asList(T...)
Methode Arrays.asList(T...)
verwendet variable Argumente eines Typs T
ohne obere Grenzen. Das Löschen dieser Methode ist Arrays.asList(Object...)
. Das bedeutet, dass es eine variable Anzahl von Argumenten eines beliebigen Typs benötigt, der sich von Object
aus erstreckt.
Da int
kein Object
, sondern ein primitiver Typ ist, also nicht als einzelnes Element von T[]
, während int[]
ein Object
selbst ist, wird es als erstes Element des T[]
Arrays ( T...
intern ist nur ein T[]
. Integer[]
wird jedoch als T[]
, wobei jeder Verweis in Integer[]
als anderes Argument an T[]
.
Und selbst wenn Sie argumentieren würden, dass der Compiler die Umwandlung von jedem Element von int[]
zu Integer
sollte, wäre das für den Compiler zu viel Arbeit. Zuerst müsste jedes Array-Element genommen und auf Integer
, dann müsste intern aus diesen Elementen ein Integer[]
werden. Das ist wirklich zu viel. Es hat bereits eine direkte Umwandlung von int[]
in das Object
, dem es folgt. Obwohl ich mir immer gewünscht habe, dass Java eine implizite Konvertierung von int[]
zu Integer[]
erlaubt, hätte dies das Leben während der Arbeit mit Generika einfacher gemacht, aber wiederum ist dies die Art, wie die Sprache entworfen wurde.
Nehmen Sie ein einfaches Beispiel:
Object[] array = new Integer[10]; // this is valid conversion
Object[] array2 = new int[10]; // this is not
Object obj = new int[10]; // this is again a valid conversion
In Ihrem Code gibt Arrays.asList(intArray)
eine ArrayList<int[]>
und nicht ArrayList<Integer>
. Sie können es nicht an den ArrayList<Integer>()
-Konstruktor übergeben.
Verbunden:
-
int[]
undInteger[]
: Was ist der Unterschied?
Ein int[]
ist nicht dasselbe wie ein Integer[]
.
Ein Array hat ein zugehöriges Klassenobjekt. Das Klassenobjekt für ein Array primitiver Ints ist [I
Das Klassenobjekt für ein Array von Integer
ist [Ljava/lang/Integer
.
Ein Array ist selbst ein Objekt, daher ist die Konvertierung zwischen zwei Objekten desselben Typs eine Identitätskonvertierung . Konvertieren zwischen zwei verschiedenen typisierten Objekten ist nicht - und int[]
und Integer[]
sind definitiv verschieden, wie durch den obigen Bytecode belegt wird.
Zu guter Letzt, bedenken Sie, dass Autoboxing nur dann wirklich zutrifft, wenn es eine Box-Konvertierung gibt .
Weil int[]
und Integer[]
beide Objekte sind. Zuerst werden primitive int
Werte gespeichert, die nicht vom Typ Object
während zweite Referenzen von Integer
Objekten speichert, die vom Typ Object
.
arrayList1
ist wirklich eine Liste der Größe eins.
arrayList1.size() = 1
arrayList3.size() = 7
Der int [] wird in ein einzelnes Objekt umgewandelt. Dieses Objekt kann nicht in Ganzzahl umgewandelt werden.