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 nullobjek 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 nullobjek 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 Dictionarykelas yang membentuk suatu LookupServicedan Listdari Stringyang mewakili kata-kata yang terkandung dalam. Bidang ini dirancang untuk tidak nulldan salah satu dari ini dilewatkan di Dictionary konstruktor.
Sekarang anggaplah implementasi "buruk" Dictionarytanpa nullmemeriksa 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 Dictionarykonstruktor dengan nullreferensi untuk wordsparameter:
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 LookupServicekelas sementara asal usulnya jauh lebih awal ( Dictionarykonstruktor). 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 nullterdeteksi? 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.