NullPointerException dalam ekspresi ternary dengan null Long

Mengapa baris kode berikut menghasilkan NullPointerException?

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null;

Saya memahami bahwa unboxing dilakukan pada null, namun mengapa?

Perhatikan itu

Long v = (Long) null;

Tidak menghasilkan Pengecualian.


person jonderry    schedule 15.12.2011    source sumber
comment
Anda melakukan v=((1==2)?Long.MAX_VALUE : (Long) null); ini selalu salah, jadi Anda selalu mencoba memasukkan null ke Long. Ini sepertinya tidak diizinkan dan memunculkan Pengecualian Anda.   -  person evildead    schedule 15.12.2011
comment
Mengapa Anda memiliki sebaris kode seperti itu? Keingintahuan intelektual atau cuplikan dari kode produksi sebenarnya?   -  person Paul    schedule 15.12.2011
comment
@Paul dan evildead, sepertinya kode contoh untuk menunjukkan pengurutan unboxing.   -  person Steven    schedule 15.12.2011
comment
Ini ada hubungannya dengan java.sun.com/ dokumen/buku/jls/third_edition/html/   -  person Steven    schedule 15.12.2011
comment
@Paul, Ini dari produksi, tetapi disederhanakan untuk menghasilkan pengecualian dalam kode sederhana.   -  person jonderry    schedule 15.12.2011
comment
Mengapa Anda tidak memecah operator ternary menjadi if/then/else? Itu mungkin membantu Anda memecahkan masalah ini.   -  person Paul    schedule 15.12.2011
comment
Itu dari produksi? Sekali lagi, keterbacaan menang atas kepintaran...   -  person Paul    schedule 15.12.2011
comment
@Paul Jika Anda membaginya menjadi if/then/else, masalahnya akan hilang.   -  person Tom Hawtin - tackline    schedule 15.12.2011
comment
Memecahnya menjadi if else menyebabkan pengecualian hilang. Saya hanya ingin tahu mengapa sintaks ternary menyebabkan pengecualian ini.   -  person jonderry    schedule 15.12.2011
comment
Terkait: stackoverflow.com/questions/3882095/ Solusinya adalah dengan memindahkan pemeran itu ke Long.MAX_VALUE Anda saat itu mengembalikan long.   -  person BalusC    schedule 15.12.2011
comment
@Tom, maka mereka harus menghapus semua contoh tersebut dari kode, membuat orang yang menulisnya membeli donat untuk tim, kemudian membaca berdasarkan urutan prioritas.   -  person Paul    schedule 15.12.2011


Jawaban (2)


Jadi terlihat jelas bahwa Anda hanya perlu melakukan boxing jika kondisinya benar, dan tidak boleh ada boxing jika kondisinya salah. Namun ekspresi operator ternary harus memiliki tipe statis tertentu. Jadi kita punya Long dan long. JLS menyatakan bahwa hasilnya akan menjadi primitif (sebaiknya - bayangkan jika operatornya, katakanlah, + atau bahkan ==). Jadi operator ternary akan memaksa unboxing, dan baru kemudian penugasan tersebut menyebabkan boxing.

Jika Anda mengganti kode dengan if-else yang setara, maka Anda hanya akan memiliki tugas dari long ke Long dan dari Long ke Long, yang tidak akan ada unboxingnya sehingga berjalan dengan baik.

IIRC, yang dibahas adalah Java Puzzlers dari Bloch & Gafter.

person Tom Hawtin - tackline    schedule 15.12.2011

Dari JSL

  1. Jika operan kedua dan ketiga memiliki tipe yang sama (yang mungkin merupakan tipe null), maka itu adalah tipe ekspresi kondisional.
  2. Jika salah satu operan kedua dan ketiga bertipe boolean dan tipe operan lainnya bertipe Boolean, maka tipe ekspresi kondisinya adalah boolean.

Dalam pernyataan berikut jenis operan kedua adalah long dan ketiga adalah Long.

Long v = 1 == 2 ? Long.MAX_VALUE :  (Long) null;

Ini akan berfungsi jika suatu ekspresi benar.

Long v= 1 == 1 ?  Long.MAX_VALUE : (Long) null;

Atau Anda dapat melemparkannya.

Long v= 1 == 2 ?  Long.valueOf(Long.MAX_VALUE) : (Long) null;
person kv-prajapati    schedule 15.12.2011
comment
Ya, saya tahu itu sedang melakukan unboxing, dan Anda tidak dapat unboxing null. Saya bertanya mengapa ia mencoba melakukan unboxing dalam kasus ini. - person jonderry; 15.12.2011
comment
Itu tidak sepenuhnya benar. Dia mencoba membuka kotak objek null Long; pemerannya tidak menjadi masalah. Anda dapat mentransmisikan null ke semua jenis objek, lihat Spesifikasi Bahasa Java bagian 5.5, di bawah Jika pemeran ke tipe referensi bukan kesalahan waktu kompilasi, ada beberapa kasus: - person Paul; 15.12.2011