Mengapa int num = Integer.getInteger ("123") memunculkan NullPointerException?

106

Kode berikut melempar NullPointerException:

int num = Integer.getInteger("123");

Apakah kompiler saya menggunakan getIntegernull karena statis? Itu tidak masuk akal!

Apa yang terjadi?

pengguna282886
sumber
3
gunakan Integer.getValue () sebagai gantinya. Posting blog ini adalah penjelasan yang bagus mengapa: konigsberg.blogspot.in/2008/04/…
Pranaysharma

Jawaban:

212

Gambar besar

Ada dua masalah yang berperan di sini:

  • Integer getInteger(String) tidak melakukan apa yang menurut Anda dilakukannya
    • Ia kembali nulldalam kasus ini
  • penugasan dari Integermenjadi intmenyebabkan unboxing otomatis
    • Sejak Integeritu null, NullPointerExceptiondibuang

Untuk mengurai (String) "123"untuk (int) 123, Anda dapat menggunakan misalnya int Integer.parseInt(String).

Referensi

Integer Referensi API


Di Integer.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 atau null, atau jika properti tidak memiliki format numerik yang benar, maka nullakan dikembalikan.

Dengan kata lain, metode ini tidak ada hubungannya dengan parsing a Stringke int/Integernilai, melainkan berkaitan dengan System.getPropertymetode.

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:

Pertanyaan-pertanyaan Terkait


Tentang autounboxing

Masalah lainnya, tentu saja, adalah bagaimana hal NullPointerExceptionitu 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 membuang NullPointerException. 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.

Pertanyaan-pertanyaan Terkait

poligenelubricants
sumber
11
Jadi 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.
MatrixFrog
5
Segera setelah saya memposting komentar itu, saya menyadari bahwa saya hanya dapat melihat sumber sebenarnya dari kelas Integer! Aku berada di jalur yang benar, kecuali bahwa ia menggunakan Integer.decodebukan Integer.parseInt, yang terlihat untuk memimpin 0xatau 0untuk mengurai nomor sebagai heksadesimal atau oktal, masing-masing.
MatrixFrog
Bagi yang bertanya Mengapa NullPointerException? : programmers.stackexchange.com/questions/158908/…
ROMANIA_engineer
2
@Oracle Bisakah Anda mencela java.lang.Integer.getInteger (String) tolong?
mjaggard
6

Silakan periksa dokumentasi metode getInteger () . Dalam metode ini, Stringparameter 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").

Sonal Patil
sumber