Ich habe einen Unterschied im Verhalten beim automatischen Entpacken zwischen Java SE 6 und Java SE 7 festgestellt. Ich frage mich, warum dies so ist, da ich keine Dokumentation zu Änderungen in diesem Verhalten zwischen diesen beiden Versionen finden kann.
Hier ist ein einfaches Beispiel:
Object[] objs = new Object[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
Dies lässt sich gut mit Javac aus Java SE 7 kompilieren. Wenn ich dem Compiler jedoch das Argument "-source 1.6" gebe, wird in der letzten Zeile ein Fehler angezeigt:
inconvertible types
found : java.lang.Object
required: int
Ich habe versucht, Java SE 6 herunterzuladen, um es mit dem nativen Compiler der Version 6 zu kompilieren (ohne die Option -source). Es stimmt zu und gibt den gleichen Fehler wie oben.
Also, was gibt es? Aus einigen weiteren Experimenten geht hervor, dass das Unboxing in Java 6 nur Werte entpacken kann, die eindeutig (zur Kompilierungszeit) vom Typ Boxed sind. Dies funktioniert beispielsweise in beiden Versionen:
Integer[] objs = new Integer[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
Es scheint also, dass zwischen Java 6 und 7 die Unboxing-Funktion so erweitert wurde, dass Objekttypen auf einen Schlag umgewandelt und entpackt werden können, ohne (zur Kompilierungszeit) zu wissen, dass der Wert vom richtigen Box-Typ ist. Beim Lesen der Java-Sprachspezifikation oder der Blog-Beiträge, die zum Zeitpunkt der Veröffentlichung von Java 7 geschrieben wurden, kann ich jedoch keine Änderung dieser Sache feststellen. Daher frage ich mich, wie die Änderung lautet und wie diese "Funktion" heißt ?
Nur eine Kuriosität: Aufgrund der Änderung ist es möglich, "falsche" Unboxings auszulösen:
Object[] objs = new Float[2];
objs[0] = new Float(5);
int myInt = (int)objs[0];
Dies lässt sich gut kompilieren, gibt jedoch zur Laufzeit eine ClassCastException aus.
Irgendein Hinweis dazu?
Integer obj = new Integer(2); int x = (int)obj;
: funktioniert auf Java 7, gibt Fehler auf Java 6.Antworten:
Es sieht so aus, als ob die Sprache in Abschnitt 5.5 Casting-Konvertierung von Java 7 JLS im Vergleich zu demselben Abschnitt in Java 5/6 JLS aktualisiert wurde , wahrscheinlich um die zulässigen Konvertierungen zu verdeutlichen.
Java 7 JLS sagt
Java 5/6:
Das Java 7 JLS enthält auch eine Tabelle (Tabelle 5.1) der zulässigen Konvertierungen (diese Tabelle ist in Java 5/6 JLS nicht enthalten) von Referenztypen zu Grundelementen. Dadurch werden Umwandlungen von Objekt zu Grundelementen explizit als einschränkende Referenzkonvertierung mit Unboxing aufgeführt.
Der Grund wird in dieser E-Mail erklärt :
quelle
Du hast recht; einfacher ausgedrückt:
Dies funktioniert in Java 7, führt jedoch zu einem Kompilierungsfehler in Java 6 und darunter. Seltsamerweise ist diese Funktion nicht prominent dokumentiert. Zum Beispiel wird es hier nicht erwähnt . Es ist fraglich, ob es sich um eine neue Funktion oder eine Fehlerbehebung (oder einen neuen Fehler?) Handelt. Weitere Informationen und Diskussionen finden Sie hier . Der Konsens scheint auf eine Unklarheit in der ursprünglichen Spezifikation hinzuweisen , die zu einer leicht inkorrekten / inkonsistenten Implementierung auf Java 5/6 führte, die in 7 behoben wurde, da dies für die Implementierung von JSR 292 (Dynamically Typed Languages) von entscheidender Bedeutung war.
Java Autoboxing hat jetzt einige weitere Fallen und Überraschungen. Beispielsweise
wird kompiliert, schlägt aber
ClassCastException
zur Laufzeit fehl (mit ). Dies wird stattdessen funktionieren:long x = (long)(int)obj;
quelle