NullPointerExceptions yang Bermanfaat di Java 14

1. Ikhtisar

Dalam tutorial ini, kami akan melanjutkan seri kami di Java 14 dengan melihat Helpful NullPointerException s, yang merupakan fitur baru yang diperkenalkan dengan versi JDK ini.

2. NullPointerException tradisional s

Dalam prakteknya, kita sering melihat atau menulis kode metode rantai itu di Java. Namun saat kode ini menampilkan NullPointerException , akan sulit untuk mengetahui dari mana pengecualian tersebut berasal.

Misalkan kita ingin mencari tahu alamat email karyawan:

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

Jika karyawan objek, getPersonalDetails () atau getEmailAddress () adalah null, JVM melempar NullPointerException :

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

Apa penyebab utama pengecualian? Sulit untuk menentukan variabel mana yang nol tanpa menggunakan debugger. Selain itu, JVM hanya akan mencetak metode, nama file, dan nomor baris yang menyebabkan pengecualian .

Di bagian selanjutnya, kita akan melihat bagaimana Java 14, melalui JEP 358, akan menyelesaikan masalah ini.

3. Bermanfaat NullPointerException s

SAP mengimplementasikan Helpful NullPointerException s untuk JVM komersial mereka pada tahun 2006. Ini diusulkan sebagai penyempurnaan komunitas OpenJDK pada Februari 2019, dan segera setelah itu, menjadi JEP. Akibatnya, fitur tersebut selesai dan didorong pada Oktober 2019 untuk rilis JDK 14 .

Intinya, JEP 358 bertujuan untuk meningkatkan keterbacaan NullPointerException , yang dihasilkan oleh JVM, dengan mendeskripsikan variabel mana yang nol .

JEP 358 menghadirkan pesan NullPointerException yang mendetail dengan menjelaskan variabel null , di samping metode, nama file, dan nomor baris. Ia bekerja dengan menganalisis instruksi bytecode program. Oleh karena itu, ia mampu menentukan dengan tepat variabel atau ekspresi mana yang nol .

Yang terpenting, pesan pengecualian rinci dimatikan secara default di JDK 14 . Untuk mengaktifkannya, kita perlu menggunakan opsi baris perintah:

-XX:+ShowCodeDetailsInExceptionMessages

3.1. Pesan Pengecualian Terperinci

Mari pertimbangkan untuk menjalankan kode lagi dengan tanda 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 informasi tambahan, kami tahu bahwa alamat email yang hilang dari detail pribadi karyawan menyebabkan pengecualian kami. Pengetahuan yang diperoleh dari peningkatan ini dapat menghemat waktu kami selama debugging.

JVM menyusun pesan pengecualian terperinci dari dua bagian. Bagian pertama mewakili operasi yang gagal, konsekuensi dari referensi menjadi null , sedangkan bagian kedua mengidentifikasi alasan referensi null :

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

Untuk membuat pesan pengecualian, JEP 358 membuat ulang bagian kode sumber yang mendorong referensi null ke tumpukan operan.

3.2. Aspek teknik

Sekarang setelah kita memiliki pemahaman yang baik tentang cara mengidentifikasi referensi null menggunakan Helpful NullPointerException , mari kita lihat beberapa aspek teknisnya.

Pertama, komputasi pesan mendetail hanya dilakukan ketika JVM itu sendiri menampilkan NullPointerException - komputasi tidak akan dilakukan jika kita secara eksplisit membuang pengecualian dalam kode Java kita. Alasan di balik ini adalah, dalam situasi ini, kemungkinan besar kita sudah meneruskan pesan yang berarti di konstruktor pengecualian.

Kedua, JEP 358 menghitung pesan secara malas, yang berarti hanya saat kita mencetak pesan pengecualian dan bukan saat pengecualian terjadi . Akibatnya, seharusnya tidak ada dampak kinerja apa pun untuk aliran JVM biasa, di mana kami menangkap dan menampilkan kembali pengecualian, karena kami tidak selalu mencetak pesan pengecualian.

Terakhir, pesan pengecualian terperinci mungkin menyertakan nama variabel lokal dari kode sumber kami . Dengan demikian, kami dapat menganggap ini sebagai risiko keamanan potensial. Namun, ini hanya terjadi ketika kita menjalankan kode yang telah dikompilasi dengan flag -g diaktifkan, yang menghasilkan dan menambahkan informasi debug ke dalam file kelas kita.

Pertimbangkan contoh sederhana yang telah kami susun untuk menyertakan informasi debug tambahan ini:

Employee employee = null; employee.getName();

Ketika kami menjalankan kode ini, pesan pengecualian mencetak nama variabel lokal:

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

Sebaliknya, tanpa informasi debug tambahan, JVM hanya menyediakan apa yang diketahuinya tentang variabel dalam pesan mendetail:

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

Alih-alih nama variabel lokal ( karyawan ), JVM mencetak indeks variabel yang ditetapkan oleh kompilator .

4. Kesimpulan

Dalam tutorial singkat ini, kita belajar tentang Helpful NullPointerException di Java 14. Seperti yang ditunjukkan di atas, pesan yang ditingkatkan membantu kita men-debug kode lebih cepat karena detail kode sumber ada di pesan pengecualian.

Seperti biasa, kode sumber lengkap artikel tersedia di GitHub.