requireNonNull()
Bir yöntemde ilk ifadeler olarak kullanmak , şu anda tanımlanmasına / istisnanın nedenini hızlı bir şekilde belirlemenize izin verir.
Stacktrace açıkça, yöntemin girişinde istisnanın atıldığını gösterir, çünkü arayan gereksinimlere / sözleşmeye saygı göstermedi.
Bir Geçme null
başka yönteme nesneyi olabilir gerçekten bir bir seferde istisna ama sorunun nedeni daha istisna üzerinde belirli çağırma atılır gibi anlamak için karmaşık olabilir provoke null
çok daha olabilir nesne.
İşte genel olarak hızlı Object.requireNonNull()
bir şekilde başarısız olmanın ve daha özel olarak veya olmamak üzere tasarlanan parametreler üzerinde boş bir kontrol yapmanın nedenini tercih etmemizi gösteren somut ve gerçek bir örnek null
.
Bir düşünelim Dictionary
bir oluşturan sınıf LookupService
ve List
içinde String
bulunan kelimeleri temsil eden. Bu alanlar değil olacak şekilde tasarlanmıştır null
ve bunlardan biri de geçirilir Dictionary
yapıcısı.
Şimdi yöntem girdisinde çek Dictionary
olmadan "kötü" bir uygulama olduğunu varsayalım null
(burada kurucu):
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);
}
}
Şimdi yapıcıyı parametre için Dictionary
bir null
referansla words
çağıralım:
Dictionary dictionary = new Dictionary(null);
// exception thrown lately : only in the next statement
boolean isFirstElement = dictionary.isFirstElement("anyThing");
JVM, NPE'yi şu ifadeye atıyor:
return words.get(0).contains(userData);
"Main" iş parçacığında özel durum java.lang.NullPointerException
LookupService.isFirstElement adresinde (LookupService.java:5)
at Dictionary.isFirstElement (Dictionary.java:15)
at Dictionary.main (Dictionary.java:22)
İstisna LookupService
sınıfta tetiklenirken , kökeninin kaynağı daha erken olur ( Dictionary
yapıcı). Genel sayı analizini daha az belirgin hale getirir.
Öyle words
null
mi? Öyle words.get(0) null
mi? Her ikisi de ? Neden biri, diğeri ya da belki ikisi de null
? Dictionary
(Yapıcı? Çağrılan yöntem?) 'De bir kodlama hatası mı? Bu bir kodlama hatası LookupService
mı? (kurucu? çağrılan yöntem?)?
Son olarak, hata kaynağını bulmak için daha fazla kod incelememiz gerekecek ve daha karmaşık bir sınıfta, ne olduğunu daha kolay anlamak için bir hata ayıklayıcı bile kullanabiliriz.
Ama neden basit bir şey (boş kontrol eksikliği) karmaşık bir sorun haline geliyor?
Çünkü alt bileşenlerde belirli bir bileşen sızıntısında tanımlanabilir ilk hata / eksikliğe izin verdik.
Bunun LookupService
yerel bir hizmet değil, uzaktaki bir hizmet ya da az sayıda hata ayıklama bilgisi içeren bir üçüncü taraf kütüphanesi olduğunu düşünün ya da daha önce null
tespit edilecek 2 kat değil, 4 veya 5 kat nesne çağırma olduğunu hayal edin. Sorunun analizi hala daha karmaşık olacaktır.
Bu yüzden tercih etme yolu:
public Dictionary(List<String> words) {
this.words = Objects.requireNonNull(words);
this.lookupService = new LookupService(words);
}
Bu şekilde, baş ağrısı yok: bu alınır alınmaz istisna atılır:
// exception thrown early : in the constructor
Dictionary dictionary = new Dictionary(null);
// we never arrive here
boolean isFirstElement = dictionary.isFirstElement("anyThing");
"Main" iş parçacığında özel durum java.lang.NullPointerException
java.util.Objects.requireNonNull'da (Objects.java:203)
com.ictionary. (Dictionary.java:15)
com.ictionary.main adresinde (Dictionary.java:24)
Burada bir yapıcı ile sorunu resmediyor, ancak yöntem çağırma aynı null olmayan kontrol kısıtlaması olabilir unutmayın.