Dies ist ein bisschen ein künstliches Beispiel, um die Situation, der ich begegne, zu verstehen, aber im Grunde genommen habe ich eine Reihe von Objekten, die in Wirklichkeit Arrays von ganzen Zahlen enthalten, und ich versuche, sie so zu interpretieren. Hier ist ein Code-Snippet, das diese Situation simuliert:
%Vor% Wenn ich das versuche, bekomme ich die Ausnahme Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [[I
Gibt es eine Möglichkeit, dies zu tun, ohne das Array zu kopieren (was ich nicht tun möchte, da foo
in der Produktion sehr groß sein wird)? Wenn nicht, warum nicht?
Sie können den intrinsischen Typ eines Java-Objekts nicht ändern, indem Sie es umwandeln. Das schließt Arrays ein. Der Objekttyp ist festgelegt, wenn das Objekt zugeordnet ist, und kann nicht geändert werden.
Das Umwandeln von Object[]
in int[][]
wird niemals funktionieren.
In diesem Fall, während int[][]
ein Untertyp von Object[]
ist, reicht dies nicht aus, um die Typumwandlung zur Laufzeit zuzulassen. Die eigentliche Regel in der JLS ( 5.5.3. Überprüft Casts zur Laufzeit ) ist dies:
"Hier ist der Algorithmus, um zu überprüfen, ob der Laufzeittyp R eines Objekts mit dem Typ T, der das Löschen (§4.6) des im Umsetzungsoperator genannten Typs ist, zuweisungskompatibel ist -time Ausnahme wird geworfen, es ist ein
ClassCastException
. " ..."Wenn R eine Klasse ist, die einen Array-Typ RC [] darstellt, dh ein Array von Komponenten vom Typ RC:"
"Wenn T ein Array vom Typ TC [] ist, also ein Array von Komponenten vom Typ TC, wird eine Laufzeitausnahme ausgelöst, sofern nicht eine der folgenden Bedingungen zutrifft:"
"TC und RC sind derselbe primitive Typ."
"TC und RC sind Referenztypen, und der Typ RC kann durch eine rekursive Anwendung dieser Laufzeitregeln für das Casting in TC umgewandelt werden."
In diesem Fall ist TC int[]
und RC ist Object
und Object
kann nicht in int[]
umgewandelt werden. Daher erhalten Sie eine Ausnahme.
Um zu verdeutlichen, warum dies muss passiert, bedenken Sie dieses (hypothetische) Beispiel:
%Vor% Unter der Annahme, dass es möglich ist, den Wert von foo
zu "werfen", worauf sollte die Variable mystery
zeigen? Es kann kein int[]
sein, weil wir keinen zugewiesen haben. Es kann keine Object
-Instanz sein, da dies die statische Typisierung unterbrechen würde.
Tatsächlich muss der "Cast" illegal sein, sonst fällt das statische Java-System auseinander.
Der Unterschied zwischen Ihrem Beispiel und mir ist, dass foo nicht wirklich ein Array von ganzen Zahlen ist, während es in meinem Fall ist. Warum kann die VM den "tatsächlichen" Typ des Objekts nicht sehen?
Der Punkt ist, dass die statische Typisierung (hauptsächlich) vom Compiler und nicht von der JVM erzwungen wird. Während die JVM (in der Theorie) herausfinden konnte, dass die Typen zur Laufzeit OK sind (und Ausnahmen auslösen, wenn dies nicht der Fall ist), kann der Compiler dies nicht tun, da im Allgemeinen nicht bestimmt werden kann sein.
Leider erstelle ich das Array nicht selbst. Ich bekomme es von einer anderen Funktion und die
Object[]
anstattint[][]
ist, soweit ich das beurteilen kann, der Nebeneffekt einiger Serialisierung, über die ich keine Kontrolle habe.
Leider musst du entweder das Array kopieren ... oder es als Object[]
verwenden und die Elemente in int[]
umwandeln, um sie zu verwenden; z.B.
Es gibt keine "Vertrauen Sie mir, es ist wirklich ein int[][]
" Option in Java.
Wenn dies ein Nebeneffekt der Serialisierung ist, dann ist die Serialisierung in gewissem Sinne unterbrochen. Natürlich wird dies nicht mit dem Standard-Java-Objekt-Serialisierungsprotokoll / -implementierung geschehen. Das behält die Typen der Objekte bei, es sei denn, Sie überschreiben sie explizit in den readObject
/ writeObject
-Methoden, usw.
Da foo
ein Array von Objekten ist, bedeutet es, dass es alles enthalten kann, nicht nur ein Array von ganzen Zahlen, so dass der Compiler es nicht in ein Array von Ganzzahlen umwandeln kann, nur weil man weiß, dass es darin ist.
Wenn Sie int[][] bar
referenz verwenden wollen, müssen Sie zuerst ein eigenes int [3][]
-Array erstellen und den Inhalt von foo
in dieses Array kopieren.
Tags und Links java