Kode berikut melempar NullPointerException
:
int num = Integer.getInteger("123");
Apakah kompiler saya menggunakan getInteger
null karena statis? Itu tidak masuk akal!
Apa yang terjadi?
Kode berikut melempar NullPointerException
:
int num = Integer.getInteger("123");
Apakah kompiler saya menggunakan getInteger
null karena statis? Itu tidak masuk akal!
Apa yang terjadi?
Jawaban:
Ada dua masalah yang berperan di sini:
Integer getInteger(String)
tidak melakukan apa yang menurut Anda dilakukannya
null
dalam kasus iniInteger
menjadi int
menyebabkan unboxing otomatis
Integer
itu null
, NullPointerException
dibuangUntuk mengurai (String) "123"
untuk (int) 123
, Anda dapat menggunakan misalnya int Integer.parseInt(String)
.
Integer
Referensi APIInteger.getInteger
Inilah yang dikatakan dokumentasi tentang apa yang dilakukan metode ini:
public static Integer getInteger(String nm)
: Menentukan nilai integer properti sistem dengan nama yang ditentukan. Jika tidak ada properti dengan nama yang ditentukan, jika nama yang ditentukan kosong ataunull
, atau jika properti tidak memiliki format numerik yang benar, makanull
akan dikembalikan.
Dengan kata lain, metode ini tidak ada hubungannya dengan parsing a String
ke int/Integer
nilai, melainkan berkaitan dengan System.getProperty
metode.
Memang ini bisa menjadi kejutan. Sangat disayangkan bahwa perpustakaan memiliki kejutan seperti ini, tetapi hal itu memberi Anda pelajaran berharga: selalu cari dokumentasi untuk mengonfirmasi apa yang dilakukan suatu metode.
Secara kebetulan, variasi dari masalah ini ditampilkan dalam Return of the Puzzlers: Schlock and Awe (TS-5186) , presentasi JavaOne Technical Session 2009 dari Josh Bloch dan Neal Gafter. Inilah slide penutupnya:
Moral
- Metode-metode aneh dan mengerikan mengintai di perpustakaan
- Beberapa memiliki nama yang terdengar tidak berbahaya
- Jika kode Anda bermasalah
- Pastikan Anda memanggil metode yang tepat
- Baca dokumentasi perpustakaan
- Untuk desainer API
- Jangan melanggar prinsip paling tidak keheranan
- Jangan melanggar hierarki abstraksi
- Jangan gunakan nama yang mirip untuk perilaku yang sangat berbeda
Untuk kelengkapannya, ada juga cara yang dianalogikan sebagai berikut Integer.getInteger
:
Masalah lainnya, tentu saja, adalah bagaimana hal NullPointerException
itu dilemparkan. Untuk fokus pada masalah ini, kita dapat menyederhanakan cuplikan sebagai berikut:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Berikut kutipan dari Effective Java 2nd Edition, Item 49: Lebih suka tipe primitif daripada primitif berkotak:
Singkatnya, gunakan primitif dalam preferensi untuk kotak primitif kapan pun Anda punya pilihan. Tipe primitif lebih sederhana dan lebih cepat. Jika Anda harus menggunakan primitif dalam kotak, berhati-hatilah! Autoboxing mengurangi verbositas, tetapi tidak bahayanya, menggunakan primitif dalam kotak. Ketika program Anda membandingkan dua kotak primitif dengan
==
operator, itu melakukan perbandingan identitas, yang hampir pasti bukan yang Anda inginkan. Ketika program Anda melakukan komputasi tipe campuran yang melibatkan primitif dalam kotak dan tanpa kotak, ia melakukan unboxing, dan ketika program Anda melakukan unboxing, ia dapat membuangNullPointerException
. Akhirnya, ketika program Anda mengemas nilai-nilai primitif, itu dapat menghasilkan pembuatan objek yang mahal dan tidak perlu.
Ada tempat di mana Anda tidak punya pilihan selain menggunakan primitif dalam kotak, misalnya obat generik, tetapi sebaliknya Anda harus secara serius mempertimbangkan apakah keputusan untuk menggunakan primitif dalam kotak dapat dibenarkan.
Integer.getInteger(s)
kira-kira setara dengan Integer.parseInt(System.getProperty(s))
? Saya rasa saya lebih suka yang kedua, meskipun lebih bertele-tele, karena menyoroti fakta bahwa Anda menarik informasi dari properti sistem.
Integer.decode
bukan Integer.parseInt
, yang terlihat untuk memimpin 0x
atau 0
untuk mengurai nomor sebagai heksadesimal atau oktal, masing-masing.
NullPointerException
? : programmers.stackexchange.com/questions/158908/…
Dari http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Menentukan nilai integer properti sistem dengan nama yang ditentukan.'
Kamu mau ini:
Integer.parseInt("123")
Silakan periksa dokumentasi metode getInteger () . Dalam metode ini, String
parameter adalah properti sistem yang menentukan nilai integer dari properti sistem dengan nama yang ditentukan. "123" bukanlah nama properti sistem apa pun, seperti yang dibahas di sini . Jika Anda ingin mengubah String ini menjadi int
, gunakan metode sebagai
int num = Integer.parseInt("123")
.