Saya telah mencatat perbedaan dalam perilaku unboxing otomatis antara Java SE 6 dan Java SE 7. Saya bertanya-tanya mengapa demikian, karena saya tidak dapat menemukan dokumentasi apa pun tentang perubahan perilaku ini antara kedua versi ini.
Berikut contoh sederhananya:
Object[] objs = new Object[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
Ini mengkompilasi dengan baik dengan javac dari Java SE 7. Namun, jika saya memberikan kompilator argumen "-source 1.6" saya mendapatkan kesalahan pada baris terakhir:
inconvertible types
found : java.lang.Object
required: int
Saya mencoba mengunduh Java SE 6 untuk dikompilasi dengan kompiler versi 6 asli (tanpa opsi -sumber). Itu setuju dan memberikan kesalahan yang sama seperti di atas.
Jadi apa yang menyebabkannya? Dari beberapa percobaan lagi terlihat bahwa unboxing di Java 6 hanya dapat membuka nilai-nilai yang jelas (pada waktu kompilasi) adalah tipe kotak. Misalnya, ini berfungsi di kedua versi:
Integer[] objs = new Integer[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];
Jadi tampaknya antara Java 6 dan 7, fitur unboxing telah ditingkatkan sehingga dapat mentransmisikan dan membuka kotak jenis objek dalam satu gerakan, tanpa mengetahui (pada waktu kompilasi) bahwa nilainya adalah jenis kotak yang sesuai. Namun, membaca Spesifikasi Bahasa Java atau posting blog yang ditulis saat Java 7 keluar, saya tidak dapat melihat perubahan apa pun dari hal ini, jadi saya bertanya-tanya apa perubahannya dan apa "fitur" ini disebut ?
Hanya keingintahuan: Karena perubahan tersebut, mungkin saja memicu unboxing yang "salah":
Object[] objs = new Float[2];
objs[0] = new Float(5);
int myInt = (int)objs[0];
Ini mengkompilasi dengan baik tetapi memberikan ClassCastException pada waktu proses.
Ada referensi tentang ini?
Integer obj = new Integer(2); int x = (int)obj;
: bekerja pada Java 7, memberikan kesalahan pada Java 6.Jawaban:
Sepertinya bahasa di bagian 5.5 Konversi Casting Java 7 JLS telah diperbarui dibandingkan dengan bagian yang sama di Java 5/6 JLS , mungkin untuk memperjelas konversi yang diizinkan.
Java 7 JLS mengatakan
Jawa 5/6:
Java 7 JLS juga berisi tabel (tabel 5.1) konversi yang diizinkan (tabel ini tidak termasuk dalam Java 5/6 JLS) dari tipe referensi hingga primitif. Ini secara eksplisit mencantumkan cast dari Object ke primitif sebagai konversi referensi yang mempersempit dengan unboxing.
Alasannya dijelaskan di email ini :
sumber
Kamu benar; sederhananya:
Ini berfungsi di Java 7, tetapi memberikan kesalahan kompilasi di Java 6 dan yang lebih lama. Anehnya, fitur ini tidak didokumentasikan secara mencolok; misalnya, tidak disebutkan di sini . Masih bisa diperdebatkan apakah itu fitur baru atau perbaikan bug (atau bug baru?), Lihat beberapa info dan diskusi terkait . Konsensus tampaknya menunjukkan ambiguitas dalam spesifikasi asli, yang menyebabkan implementasi yang sedikit salah / tidak konsisten pada Java 5/6, yang diperbaiki pada 7, karena sangat penting untuk implementasi JSR 292 (Dynamically Typed Languages).
Autoboxing Java kini memiliki lebih banyak jebakan dan kejutan. Sebagai contoh
akan dikompilasi, tetapi gagal (dengan
ClassCastException
) saat runtime. Ini, sebagai gantinya, akan berfungsi:long x = (long)(int)obj;
sumber