Menggunakan requireNonNull()
sebagai pernyataan pertama dalam suatu metode memungkinkan untuk mengidentifikasi sekarang / puasa penyebab pengecualian.
Stacktrace menunjukkan dengan jelas bahwa pengecualian dilemparkan segera setelah masuknya metode karena penelepon tidak menghormati persyaratan / kontrak.
Melewati suatu null
objek ke metode lain mungkin memang memprovokasi pengecualian pada suatu waktu, tetapi penyebab masalahnya mungkin lebih rumit untuk dipahami karena pengecualian akan dilemparkan dalam doa khusus pada null
objek yang mungkin jauh lebih jauh.
Berikut ini adalah contoh nyata dan nyata yang menunjukkan mengapa kita harus memilih gagal cepat secara umum dan lebih khusus menggunakan Object.requireNonNull()
atau cara apa pun untuk melakukan pemeriksaan tanpa nol pada parameter yang dirancang bukan null
.
Misalkan Dictionary
kelas yang membentuk suatu LookupService
dan List
dari String
yang mewakili kata-kata yang terkandung dalam. Bidang ini dirancang untuk tidak null
dan salah satu dari ini dilewatkan di Dictionary
konstruktor.
Sekarang anggaplah implementasi "buruk" Dictionary
tanpa null
memeriksa entri metode (di sini adalah konstruktor):
public class Dictionary {
private final List<String> words;
private final LookupService lookupService;
public Dictionary(List<String> words) {
this.words = this.words;
this.lookupService = new LookupService(words);
}
public boolean isFirstElement(String userData) {
return lookupService.isFirstElement(userData);
}
}
public class LookupService {
List<String> words;
public LookupService(List<String> words) {
this.words = words;
}
public boolean isFirstElement(String userData) {
return words.get(0).contains(userData);
}
}
Sekarang, mari kita panggil Dictionary
konstruktor dengan null
referensi untuk words
parameter:
Dictionary dictionary = new Dictionary(null);
// exception thrown lately : only in the next statement
boolean isFirstElement = dictionary.isFirstElement("anyThing");
JVM melempar NPE pada pernyataan ini:
return words.get(0).contains(userData);
Pengecualian di utas "utama" java.lang.NullPointerException
di LookupService.isFirstElement (LookupService.java#)
di Dictionary.isFirstElement (Dictionary.java:15)
di Dictionary.main (Dictionary.java:22)
Pengecualian dipicu di LookupService
kelas sementara asal usulnya jauh lebih awal ( Dictionary
konstruktor). Itu membuat analisis masalah secara keseluruhan menjadi kurang jelas.
Benarkah words
null
? Benarkah words.get(0) null
? Keduanya? Mengapa yang satu, yang lain atau mungkin keduanya null
? Apakah ini merupakan kesalahan pengkodean dalam Dictionary
(konstruktor? Metode yang dipanggil?)? Apakah ada kesalahan pengkodean LookupService
? (konstruktor? metode yang dipanggil?)?
Akhirnya, kita harus memeriksa lebih banyak kode untuk menemukan asal kesalahan dan dalam kelas yang lebih kompleks bahkan mungkin menggunakan debugger untuk lebih mudah memahami apa yang terjadi.
Tetapi mengapa hal sederhana (kurangnya cek nol) menjadi masalah yang kompleks?
Bayangkan itu
Karena kami mengizinkan bug awal / kekurangan dapat diidentifikasi pada kebocoran komponen tertentu pada komponen yang lebih rendah.
LookupService
itu bukan layanan lokal tetapi layanan jarak jauh atau perpustakaan pihak ketiga dengan sedikit informasi debug atau bayangkan bahwa Anda tidak memiliki 2 lapisan tetapi 4 atau 5 lapisan objek doa sebelum null
terdeteksi? Masalahnya akan lebih kompleks untuk dianalisis.
Jadi cara untuk mendukung adalah:
public Dictionary(List<String> words) {
this.words = Objects.requireNonNull(words);
this.lookupService = new LookupService(words);
}
Dengan cara ini, tidak ada sakit kepala: kami mendapatkan pengecualian yang dilemparkan segera setelah ini diterima:
// exception thrown early : in the constructor
Dictionary dictionary = new Dictionary(null);
// we never arrive here
boolean isFirstElement = dictionary.isFirstElement("anyThing");
Pengecualian di utas "utama" java.lang.NullPointerException
di java.util.Objects.requireNonNull (Objects.java:203)
di com.Dictionary. (Dictionary.java:15)
di com.Dictionary.main (Dictionary.java:24)
Perhatikan bahwa di sini saya mengilustrasikan masalah dengan konstruktor tetapi pemanggilan metode dapat memiliki kendala periksa nihil yang sama.