Pengecualian NullPointer Berguna di Java 14

1. Gambaran keseluruhan

Dalam tutorial ini, kami akan meneruskan siri kami di Java 14 dengan melihat Helpful NullPointerException s, yang merupakan ciri baru yang diperkenalkan dengan versi JDK ini.

2. Tradisional NullPointerException s

Dalam praktiknya, kita sering melihat atau menulis kod yang mengaitkan kaedah di Jawa. Tetapi apabila kod ini membuang NullPointerException , sukar untuk mengetahui dari mana asalnya pengecualian.

Anggaplah kita ingin mengetahui alamat e-mel pekerja:

String emailAddress = employee.getPersonalDetails().getEmailAddress().toLowerCase();

Sekiranya objek pekerja , getPersonalDetails () atau getEmailAddress () adalah nol, JVM membuang NullPointerException :

Exception in thread "main" java.lang.NullPointerException at com.baeldung.java14.npe.HelpfulNullPointerException.main(HelpfulNullPointerException.java:10)

Apakah punca pengecualian? Sukar untuk menentukan pemboleh ubah yang nol tanpa menggunakan penyahpepijat. Selain itu, JVM hanya akan mencetak kaedah, nama fail, dan nombor baris yang menyebabkan pengecualian .

Di bahagian seterusnya, kita akan melihat bagaimana Java 14, melalui JEP 358, akan menyelesaikan masalah ini.

3. sedia membantu NullPointerException s

SAP mengimplementasikan Helpful NullPointerException untuk JVM komersial mereka pada tahun 2006. Ia dicadangkan sebagai peningkatan kepada komuniti OpenJDK pada Februari 2019, dan dengan cepat selepas itu, ia menjadi JEP. Akibatnya, ciri ini selesai dan diturunkan pada Oktober 2019 untuk pelepasan JDK 14 .

Pada dasarnya, JEP 358 bertujuan untuk meningkatkan kebolehbacaan NullPointerException s, yang dihasilkan oleh JVM, dengan menerangkan pemboleh ubah mana yang nol .

JEP 358 membawa mesej NullPointerException terperinci dengan menerangkan pemboleh ubah null , di samping kaedah, nama fail, dan nombor baris. Ia berfungsi dengan menganalisis arahan bytecode program. Oleh itu, ia dapat menentukan dengan tepat pemboleh ubah atau ungkapan yang nol .

Yang paling penting, mesej pengecualian terperinci dimatikan secara lalai dalam JDK 14 . Untuk mengaktifkannya, kita perlu menggunakan pilihan baris perintah:

-XX:+ShowCodeDetailsInExceptionMessages

3.1. Mesej Pengecualian Terperinci

Mari pertimbangkan untuk menjalankan kod lagi dengan bendera ShowCodeDetailsInExceptionMessages diaktifkan:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because the return value of "com.baeldung.java14.npe.HelpfulNullPointerException$PersonalDetails.getEmailAddress()" is null at com.baeldung.java14.npe.HelpfulNullPointerException.main(HelpfulNullPointerException.java:10)

Kali ini, dari maklumat tambahan, kami mengetahui bahawa alamat e-mel maklumat peribadi pekerja yang hilang menyebabkan pengecualian kami. Pengetahuan yang diperoleh dari peningkatan ini dapat menjimatkan masa kita semasa melakukan penyahpepijatan.

JVM menyusun mesej pengecualian terperinci dari dua bahagian. Bahagian pertama mewakili operasi yang gagal, akibat dari rujukan menjadi nol , sementara bahagian kedua mengenal pasti sebab rujukan nol :

Cannot invoke "String.toLowerCase()" because the return value of "getEmailAddress()" is null

Untuk membina mesej pengecualian, JEP 358 membuat semula bahagian kod sumber yang mendorong rujukan nol ke timbunan operan.

3.2. Aspek Teknikal

Sekarang kita mempunyai pemahaman yang baik tentang bagaimana mengenal pasti rujukan nol menggunakan NullPointerException Berguna , mari kita lihat beberapa aspek teknikalnya.

Pertama, pengiraan mesej terperinci hanya dilakukan apabila JVM sendiri melemparkan NullPointerException - pengiraan tidak akan dilakukan jika kita secara eksplisit membuang pengecualian dalam kod Java kita. Sebab di sebalik ini adalah bahawa, dalam situasi ini, kemungkinan besar kita sudah menyampaikan mesej yang bermakna dalam pengecualian pembina.

Kedua, JEP 358 mengira mesej dengan malas, yang bermaksud hanya apabila kita mencetak mesej pengecualian dan bukan ketika pengecualian berlaku . Akibatnya, tidak seharusnya ada kesan prestasi untuk aliran JVM biasa, di mana kita menangkap dan mengubah semula pengecualian, kerana kita tidak selalu mencetak pesan pengecualian.

Akhirnya, mesej pengecualian terperinci mungkin merangkumi nama pemboleh ubah tempatan dari kod sumber kami . Oleh itu, kita boleh menganggap ini sebagai risiko keselamatan yang berpotensi. Walau bagaimanapun, ini hanya berlaku apabila kita menjalankan kod yang disusun dengan bendera -g diaktifkan, yang menghasilkan dan menambahkan maklumat debug ke dalam fail kelas kita.

Pertimbangkan contoh mudah yang telah kami kumpulkan untuk memasukkan maklumat debug tambahan ini:

Employee employee = null; employee.getName();

Apabila kami menjalankan kod ini, mesej pengecualian mencetak nama pemboleh ubah tempatan:

Cannot invoke "com.baeldung.java14.npe.HelpfulNullPointerException$Employee.getName()" because "employee" is null

Sebaliknya, tanpa maklumat debug tambahan, JVM hanya memberikan apa yang diketahui mengenai pemboleh ubah dalam mesej terperinci:

Cannot invoke "com.baeldung.java14.npe.HelpfulNullPointerException$Employee.getName()" because "" is null

Daripada nama pemboleh ubah tempatan ( pekerja ), JVM mencetak indeks pemboleh ubah yang diberikan oleh penyusun .

4. Kesimpulan

Dalam tutorial ringkas ini, kami belajar mengenai Helpful NullPointerException s di Java 14. Seperti yang ditunjukkan di atas, mesej yang diperbaiki membantu kami melakukan debug kod dengan lebih cepat kerana perincian kod sumber yang terdapat dalam mesej pengecualian.

Seperti biasa, kod sumber penuh artikel terdapat di GitHub.