Auto-unboxing perlu ternary if-else

23

Bagian kode ini berfungsi dengan baik: -

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

Tapi ini melempar pengecualian null-pointer, sementara Eclipse memperingatkan bahwa ada kebutuhan untuk membuka kotak secara otomatis: -

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

Mengapa begitu, bisakah seseorang membimbing?

91StarSky
sumber

Jawaban:

22

Jenis ekspresi kondisional terner

1 <= 3 ? nullInt : -1

is int(JLS berisi beberapa tabel yang menggambarkan jenis operator kondisional ternary tergantung pada jenis operan ke-2 dan ke-3).

Oleh karena itu, ketika mencoba untuk membuka kotak nullIntke int, a NullPointerExceptiondilemparkan.

Untuk mendapatkan perilaku cuplikan if-else Anda, Anda perlu menulis:

1 <= 3 ? nullInt : Integer.valueOf(-1)

Sekarang jenis ekspresi akan Integer, jadi tidak ada unboxing akan terjadi.

Eran
sumber
4
Hanya untuk menambah jawaban Anda, berikut adalah tabel yang disebutkan: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen
3

Saya cukup yakin bahwa argumen untuk operator ternary harus dari jenis yang sama. Karena Anda menggunakan -1 dan beberapa nullintkompiler konstan mencoba membuka kotak nullintuntuk mendapatkan nilai. Dan kemudian autobox untuk menyimpannya dalam secondNullvariabel.

The Tosters
sumber
3

Ini karena ketika dua operan untuk operator kondisional ? :adalah tipe primitif dan tipe referensi kemasnya , konversi unboxing dilakukan ( JLS §15.25.2 ):

Jenis ekspresi kondisional numerik ditentukan sebagai berikut:

  • ...
  • Jika salah satu operan kedua dan ketiga adalah tipe T primitif, dan jenis yang lain adalah hasil dari menerapkan konversi tinju (§5.1.7) ke T, maka jenis ekspresi kondisional adalah T.

Secara umum, mengganti ifpernyataan dengan ? :ekspresi tidak selalu mempertahankan makna kode, karena ? :ekspresi itu sendiri harus memiliki tipe waktu kompilasi. Itu berarti ketika jenis kedua operan berbeda, konversi harus dilakukan untuk satu atau keduanya sehingga hasilnya memiliki tipe waktu kompilasi yang konsisten.

kaya3
sumber
2

Yang ini berhasil (di Jawa 1.8):

Integer secondNull = 1 <= 3 ? null : -1;
Catalina Chircu
sumber