Niemand mag NullPointerException! Gibt es eine Möglichkeit, sie zu vermeiden? Vielleicht. .
In diesem Artikel werden die folgenden Technologien besprochen
1.Optionaler Typ (neu eingeführt in Java 8)
2.Objects-Klasse (Original in Java 7)
Optionale Klasse in Java 8
Was ist das?
1. Neue Typen, die in Java 8 eingeführt wurden
2. Es wird als Wrapper für ein Objekt eines bestimmten Typs oder für Szenarien verwendet, in denen kein Objekt (null) vorhanden ist
Einfach ausgedrückt ist es eine bessere Alternative für den Umgang mit Nullwerten (Achtung: Auf den ersten Blick ist es möglicherweise nicht so offensichtlich).
Grundlegende Verwendung
Es ist ein Typ (eine Klasse) – wie erstellt man also eine Instanz dieses Typs?
Verwenden Sie einfach die drei statischen Methoden:
Kopieren Sie den Codecode wie folgt:
public static Optional<String> stringOptional(String input) {
return Optional.of(input);
}
Einfach und klar: Erstellen Sie einen optionalen Wrapper, der diesen Wert enthält. Denken Sie daran: Wenn dieser Wert null ist, wird NPE ausgelöst!
Kopieren Sie den Codecode wie folgt:
public static Optional<String> stringNullableOptional(String input) {
if (!new Random().nextBoolean()) {
Eingabe = null;
}
return Optional.ofNullable(input);
}
Ich persönlich finde es besser. Auf diese Weise besteht kein NPE-Risiko – wenn die Eingabe null ist, wird ein leeres Optional zurückgegeben.
Kopieren Sie den Codecode wie folgt:
public static Optional<String> emptyOptional() {
return Optional.empty();
}
Wenn Sie wirklich nur einen „Null“-Wert zurückgeben möchten. Ein „leerer“ Wert bedeutet nicht null.
Okay, wie kann man Optional konsumieren/verwenden?
Kopieren Sie den Codecode wie folgt:
öffentliches statisches Leerzeichen verbrauchendOptional() {
Optional<String> Wrapped = Optional.of("aString");
if (wrapped.isPresent()) {
System.out.println("Got string - " + Wrapped.get());
}
anders {
System.out.println("Verstanden!");
}
}
Der einfache Weg besteht darin, zu überprüfen, ob der optionale Wrapper tatsächlich einen Wert hat (mit der Methode isPresent) – Sie werden sich fragen, welchen Vorteil dies gegenüber der Verwendung von if(myObj != null) hat. Keine Sorge, ich werde das klar erklären.
Kopieren Sie den Codecode wie folgt:
öffentliche statische Leere verbrauchendeNullableOptional() {
String-Eingabe = null;
if (new Random().nextBoolean()) {
input = "iCanBeNull";
}
Optional<String> Wrapped = Optional.ofNullable(input);
System.out.println(wrapped.orElse("default"));
}
Sie können die orElse-Methode verwenden, sodass Sie, wenn der gekapselte Wert tatsächlich ein Nullwert ist, einen Standardwert zurückgeben können – die Vorteile liegen auf der Hand. Beim Extrahieren des realen Werts können Sie die offensichtlich redundante Methode des Aufrufs der ifPresent-Methode vermeiden.
Kopieren Sie den Codecode wie folgt:
öffentliche statische Leere verbrauchendeEmptyOptional() {
String-Eingabe = null;
if (new Random().nextBoolean()) {
input = "iCanBeNull";
}
Optional<String> Wrapped = Optional.ofNullable(input);
System.out.println(wrapped.orElseGet(
() -> {
return „defaultBySupplier“;
}
));
}
Ich bin etwas verwirrt darüber. Warum gibt es zwei unterschiedliche Methoden für den gleichen Zweck? orElse und orElseGet können offensichtlich überladen werden (mit demselben Namen, aber unterschiedlichen Parametern).
Wie auch immer, der offensichtliche Unterschied zwischen diesen beiden Methoden sind ihre Parameter – Sie können Lambda-Ausdrücke anstelle von Instanzen von Supplier verwenden, um dies zu erreichen (eine funktionale Schnittstelle).
Warum ist die Verwendung von Optional besser als die allgemeine Nullprüfung?
1. Der größte Vorteil der Verwendung von Optional besteht darin, dass Sie Ihre Absicht klarer ausdrücken können – die Rückgabe eines Nullwerts führt dazu, dass Verbraucher verwirrt werden (wenn NPE auftritt), ob dies absichtlich zurückgegeben wird, daher müssen Sie die Position in Javadoc überprüfen . Die Verwendung von Optional ist recht einfach.
2. Mit Optional können Sie NPE vollständig vermeiden – wie oben erwähnt, kann uns die Verwendung von Optional.ofNullable, orElse und orElseGet von NPE fernhalten.
Ein weiterer Retter!
Schauen Sie sich dieses Code-Snippet an und kopieren Sie den folgenden Code:
Paket com.abhirockzz.wordpress.npesaviors;
java.util.Map importieren;
java.util.Objects importieren;
öffentliche Klasse UsingObjects {
String getVal(Map<String, String> aMap, String key) {
return aMap.containsKey(key) ? aMap.get(key) : null;
}
public static void main(String[] args) {
UsingObjects obj = new UsingObjects();
obj.getVal(null, "dummy");
}
}
Welches könnte leer sein?
1. Kartenobjekt
2. Für die Suche verwendeter Schlüssel
3. Diese Instanz des Methodenaufrufs
Wenn NPE ausgelöst wird, wie können wir dann feststellen, welches NPE null ist?
Kopieren Sie den Codecode wie folgt:
Paket com.abhirockzz.wordpress.npesaviors;
java.util.Map importieren;
java.util.Objects importieren;
öffentliche Klasse UsingObjects {
String getValSafe(Map<String, String> aMap, String key) {
Map<String, String> safeMap = Objects.requireNonNull(aMap,
„Karte ist null“);
String safeKey = Objects.requireNonNull(key, "Key is null");
return safeMap.containsKey(safeKey) ? safeMap.get(safeKey) : null;
}
public static void main(String[] args) {
UsingObjects obj = new UsingObjects();
obj.getValSafe(null, "dummy");
}
}
requireNonNull-Methode
1. Wenn das Objekt nicht null ist, wird es selbst zurückgegeben
2. Wenn der Wert null ist, enthält die zurückgegebene NPE die angegebene Nachricht.
Warum ist es besser als if(myObj!=null)?
In der Stapelverfolgung, die Sie sehen, ist der Aufruf der Objects.requireNonNull-Methode deutlich zu erkennen. In Kombination mit Ihrem eigenen Fehlerprotokoll können Sie so das Problem schneller lokalisieren. . . Zumindest ist es meiner Meinung nach schneller.
Sie können auch Ihren eigenen Validator anpassen, indem Sie beispielsweise einen einfachen Validator implementieren, um sicherzustellen, dass keine Nullwerte vorhanden sind.
Kopieren Sie den Codecode wie folgt:
java.util.Collections importieren;
java.util.List importieren;
java.util.Objects importieren;
import java.util.function.Predicate;
öffentliche Klasse RandomGist {
public static <T> T requireNonEmpty(T object, Predicate<T> predicate, String msgToCaller){
Objects.requireNonNull(object);
Objects.requireNonNull(predicate);
if (predicate.test(object)){
throw new IllegalArgumentException(msgToCaller);
}
Rückgabeobjekt;
}
public static void main(String[] args) {
//Verwendung 1: eine leere Zeichenfolge (absichtlich)
String s = "";
System.out.println(requireNonEmpty(Objects.requireNonNull(s), (s1) -> s1.isEmpty() , "Mein String ist leer!"));
//Verwendung 2: eine leere Liste (absichtlich)
Liste list = Collections.emptyList();
System.out.println(requireNonEmpty(Objects.requireNonNull(list), (l) -> l.isEmpty(), "List is Empty!").size());
//Verwendung 3: ein leerer Benutzer (absichtlich)
Benutzer user = neuer Benutzer("");
System.out.println(requireNonEmpty(Objects.requireNonNull(user), (u) -> u.getName().isEmpty(), "User is Empty!"));
}
private statische Klasse Benutzer {
privater String-Name;
öffentlicher Benutzer(Stringname){
this.name = Name;
}
öffentlicher String getName(){
Rückgabename;
}
}
}
Lassen Sie nicht zu, dass NPE an der falschen Stelle zur Belastung wird. Wir verfügen über viele Tools, um NPEs besser zu bekämpfen und sie sogar vollständig zu beseitigen!