Zauważyłem różnicę w zachowaniu automatycznego rozpakowywania między Java SE 6 i Java SE 7. Zastanawiam się, dlaczego tak jest, ponieważ nie mogę znaleźć żadnej dokumentacji dotyczącej zmian w tym zachowaniu między tymi dwiema wersjami.
Oto prosty przykład:
Object[] objs = new Object[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
Kompiluje się dobrze z javac z Java SE 7. Jeśli jednak podam kompilatorowi argument „-source 1.6”, w ostatnim wierszu pojawi się błąd:
inconvertible types
found : java.lang.Object
required: int
Próbowałem pobrać Java SE 6 do kompilacji z natywnym kompilatorem w wersji 6 (bez żadnej opcji -source). Zgadza się i daje ten sam błąd co powyżej.
Więc co daje? Po dalszych eksperymentach wydaje się, że rozpakowanie w Javie 6 może tylko rozpakować wartości, które wyraźnie (w czasie kompilacji) są typu pudełkowego. Na przykład działa to w obu wersjach:
Integer[] objs = new Integer[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
Wygląda więc na to, że między Javą 6 a 7 funkcja rozpakowywania została ulepszona, dzięki czemu może rzucać i rozpakowywać typy obiektów za jednym zamachem, bez wiedzy (w czasie kompilacji), że wartość jest odpowiedniego typu pudełkowego. Jednak czytając specyfikację języka Java lub posty na blogu, które zostały napisane w czasie, gdy pojawiła się Java 7, nie widzę żadnej zmiany w tej kwestii, więc zastanawiam się, na czym ta zmiana polega i jak nazywa się ta „funkcja” ?
Ciekawostka: w związku z tą zmianą możliwe jest wywołanie „niewłaściwego” unboxingu:
Object[] objs = new Float[2];
objs[0] = new Float(5);
int myInt = (int)objs[0];
Kompiluje się dobrze, ale daje ClassCastException w czasie wykonywania.
Jakieś wzmianki na ten temat?
Integer obj = new Integer(2); int x = (int)obj;
: działa na Javie 7, wyświetla błąd w Javie 6.