java check best - Vermeiden von! = Null-Anweisungen




15 Answers

Das klingt für mich wie ein ziemlich allgemeines Problem, mit dem sich Junior- und Intermediate-Entwickler zu einem bestimmten Zeitpunkt konfrontiert sehen: Sie kennen die Verträge, an denen sie beteiligt sind, nicht oder vertrauen ihnen nicht, und sie überprüfen defensiv ihre Nullwerte. Wenn sie ihren eigenen Code schreiben, neigen sie dazu, NULL-Werte zurückzugeben, um etwas anzuzeigen, sodass der Anrufer nach NULL-Werten suchen muss.

Anders ausgedrückt: Es gibt zwei Fälle, in denen die Nullprüfung auftritt:

  1. Null ist eine gültige Antwort im Sinne des Vertrags; und

  2. Wo es keine gültige Antwort ist.

(2) ist einfach. Verwenden Sie entweder NullPointerException Anweisungen (Assertions) oder erlauben Sie Fehler (z. B. NullPointerException ). Assertionen sind eine stark unterbenutzte Java-Funktion, die in 1.4 hinzugefügt wurde. Die Syntax lautet:

assert <condition>

oder

assert <condition> : <object>

Dabei ist <condition> ein boolescher Ausdruck und <object> ein Objekt, dessen Ausgabe der toString() Methode in den Fehler aufgenommen wird.

Eine assert Anweisung wirft einen Error ( AssertionError ) aus, wenn die Bedingung nicht erfüllt ist. Standardmäßig ignoriert Java Assertions. Sie können Zusicherungen aktivieren, indem Sie die Option -ea an die JVM übergeben. Sie können Assertions für einzelne Klassen und Pakete aktivieren und deaktivieren. Dies bedeutet, dass Sie den Code während der Entwicklung und des Tests mit den Assertions validieren und in einer Produktionsumgebung deaktivieren können, obwohl meine Tests kaum Auswirkungen auf die Performance von Assertions gezeigt haben.

Das Verwenden von Assertions in diesem Fall ist in Ordnung, da der Code einfach fehlschlägt. Dies ist der Fall, wenn Sie Assertions verwenden. Der einzige Unterschied besteht darin, dass es mit Behauptungen früher, sinnvoller und möglicherweise mit zusätzlichen Informationen geschehen kann, was Ihnen helfen kann, herauszufinden, warum es passiert, wenn Sie es nicht erwartet hätten.

(1) ist etwas schwieriger. Wenn Sie den Code, den Sie anrufen, nicht kontrollieren können, stecken Sie fest. Wenn null eine gültige Antwort ist, müssen Sie danach suchen.

Wenn es sich jedoch um Code handelt, den Sie kontrollieren (und dies ist häufig der Fall), ist es eine andere Geschichte. Vermeiden Sie die Verwendung von Nullen als Antwort. Mit Methoden, die Sammlungen zurückgeben, ist es ganz einfach: Leere Sammlungen (oder Arrays) anstelle von Nullen werden fast immer zurückgegeben.

Bei Nicht-Sammlungen könnte es schwieriger sein. Betrachten Sie dies als Beispiel: Wenn Sie über folgende Schnittstellen verfügen:

public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

Parser nimmt rohe Benutzereingaben entgegen und findet etwas zu tun, wenn Sie beispielsweise eine Befehlszeilenschnittstelle für etwas implementieren. Jetzt können Sie den Vertrag so einstellen, dass er null zurückgibt, wenn es keine geeignete Aktion gibt. Das führt zur Nullprüfung, über die Sie sprechen.

Eine alternative Lösung ist, niemals null zurückzugeben und stattdessen das Null-Objekt-Muster zu verwenden :

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

Vergleichen Sie:

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}

zu

ParserFactory.getParser().findAction(someInput).doSomething();

Dies ist ein viel besseres Design, da es zu prägnanterem Code führt.

Vielleicht ist es jedoch durchaus angebracht, dass die findAction () -Methode eine Exception mit einer aussagekräftigen Fehlermeldung auslöst - insbesondere in diesem Fall, wenn Sie auf Benutzereingaben angewiesen sind. Es wäre viel besser für die findAction-Methode, eine Exception auszulösen, als für die aufrufende Methode, die mit einer einfachen NullPointerException ohne Erklärung explodiert.

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

Oder wenn Sie denken, dass der Try / Catch-Mechanismus zu hässlich ist, anstatt Do Nothing. Ihre Standardaktion sollte dem Benutzer eine Rückmeldung geben.

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}
practice if

Ich verwende object != null , um die NullPointerException zu vermeiden.

Gibt es eine gute Alternative dazu?

Zum Beispiel:

if (someobject != null) {
    someobject.doCalc();
}

Dadurch wird eine NullPointerException , wenn unbekannt ist, ob das Objekt null oder nicht.

Beachten Sie, dass die akzeptierte Antwort möglicherweise nicht mehr aktuell ist. Weitere Informationen finden Sie unter https://.com/a/2386013/12943 .




Wenn Nullwerte nicht zulässig sind

Wenn Ihre Methode extern aufgerufen wird, beginnen Sie mit etwas wie folgt:

public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }

In der restlichen Methode wissen Sie dann, dass das object nicht null ist.

Wenn es sich um eine interne Methode (nicht Teil einer API) handelt, dokumentieren Sie einfach, dass sie nicht null sein kann, und das ist es.

Beispiel:

public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}

Wenn Ihre Methode jedoch nur den Wert weitergibt und die nächste Methode den Wert weitergibt, kann dies problematisch werden. In diesem Fall können Sie das Argument wie oben prüfen.

Wenn null erlaubt ist

Das hängt wirklich davon ab. Wenn ich finde, dass ich oft so etwas mache:

if (object == null) {
  // something
} else {
  // something else
}

Also verzweige ich und mache zwei völlig verschiedene Dinge. Es gibt kein hässliches Code-Snippet, da ich abhängig von den Daten zwei verschiedene Dinge tun muss. Soll ich zum Beispiel an der Eingabe arbeiten oder einen guten Standardwert berechnen?

Es ist eigentlich selten für mich, die Redewendung " if (object != null && ... " zu verwenden.

Es kann einfacher sein, Ihnen Beispiele zu geben, wenn Sie Beispiele zeigen, wo Sie normalerweise das Idiom verwenden.




Wenn undefinierte Werte nicht zulässig sind:

Sie können Ihre IDE so konfigurieren, dass Sie vor potenzieller Null-Dereferenzierung gewarnt wird. ZB in Eclipse siehe Voreinstellungen> Java> Compiler> Fehler / Warnungen / Nullanalyse .

Wenn undefinierte Werte zulässig sind:

Wenn Sie eine neue API definieren möchten, bei der undefinierte Werte sinnvoll sind , verwenden Sie das Optionsmuster (ist möglicherweise aus funktionalen Sprachen bekannt). Es hat folgende Vorteile:

  • In der API wird explizit angegeben, ob eine Eingabe oder eine Ausgabe vorhanden ist oder nicht.
  • Der Compiler zwingt Sie, den "undefinierten" Fall zu behandeln.
  • Die Option ist eine Monade. Daher ist keine ausführliche Nullprüfung erforderlich. Verwenden Sie einfach map / foreach / getOrElse oder einen ähnlichen Kombinator, um den Wert sicher zu verwenden (example) .

Java 8 verfügt über eine eingebaute Optional Klasse (empfohlen). Für frühere Versionen gibt es Bibliotheksalternativen, zum Beispiel die Option Guava oder die Option FunctionalJava . Wie bei vielen Mustern im funktionalen Stil führt die Verwendung von Option in Java (sogar 8) zu einer gewissen Anzahl von Boilerplates, die Sie mit einer weniger ausführlichen JVM-Sprache (z. B. Scala oder Xtend) reduzieren können.

Wenn Sie mit einer API arbeiten müssen, die möglicherweise Nullen zurückgibt , können Sie in Java nicht viel tun. Xtend und Groovy haben den Elvis-Operator ?: Und den nullsicheren Dereferenzierungsoperator ?. Beachten Sie jedoch, dass dies im Falle einer Nullreferenz null zurückgibt, so dass die korrekte Behandlung von Null nur "verschoben" wird.




Mit Java 8 steht die neue Klasse java.util.Optional , die einige der Probleme löst. Man kann zumindest sagen, dass es die Lesbarkeit des Codes verbessert und im Falle von öffentlichen APIs den Vertrag der API für den Client-Entwickler klarer macht.

Sie arbeiten so:

Ein optionales Objekt für einen bestimmten Typ ( Fruit ) wird als Rückgabetyp einer Methode erstellt. Es kann leer sein oder ein Fruit enthalten:

public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}

Sehen Sie sich nun diesen Code an, in dem wir eine Fruit für eine bestimmte Fruit-Instanz suchen:

Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}

Mit dem map() Operator können Sie eine Berechnung an einem optionalen Objekt durchführen oder einen Wert daraus extrahieren. orElse() können Sie einen Fallback für fehlende Werte bereitstellen.

String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");

Natürlich ist die Überprüfung auf null / leere Werte immer noch notwendig, aber zumindest ist sich der Entwickler bewusst, dass der Wert leer ist und das Risiko des Vergessens der Überprüfung begrenzt ist.

In einer von Grund auf mit Hilfe von Optional API, wenn ein Rückgabewert leer ist und nur ein einfaches Objekt zurückgibt, wenn es nicht null (Konvention), kann der Clientcode die Überprüfung von einfachen Objektrückgabewerten auf Null zurücksetzen.

Natürlich könnte Optional auch als Methodenargument verwendet werden. In einigen Fällen ist dies eine bessere Möglichkeit, optionale Argumente als 5 oder 10 Überladungsmethoden anzugeben.

Optional bietet andere praktische Methoden, z. B. orElse , die die Verwendung eines Standardwerts zulassen, und ifPresent , das mit Lambda-Ausdrücken funktioniert.

Ich lade Sie ein, diesen Artikel (meine Hauptquelle für das Schreiben dieser Antwort) zu lesen, in dem die NullPointerException (und in der Regel der Nullzeiger) sowie die ( Optional ) Lösung von Optional gut erläutert sind: Java Optionale Objekte .




  • Wenn Sie der Meinung sind, dass ein Objekt nicht null sein sollte (oder ein Fehler ist), verwenden Sie eine Bestätigung.
  • Wenn Ihre Methode keine Nullparameter akzeptiert, sagen Sie es im Javadoc und verwenden Sie eine Assert-Anweisung.

Sie müssen nur auf object! = Null prüfen, wenn Sie den Fall behandeln möchten, in dem das Objekt null sein kann.

Es gibt einen Vorschlag zum Hinzufügen neuer Anmerkungen in Java7, um bei null / notnull-Parametern zu helfen: http://tech.puredanger.com/java7/#jsr308




Das Google Collections-Framework bietet eine gute und elegante Möglichkeit, die Nullprüfung durchzuführen.

Es gibt eine Methode in einer Bibliotheksklasse wie folgt:

static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}

Und die Verwendung ist (mit import static ):

...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...

Oder in deinem Beispiel:

checkNotNull(someobject).doCalc();



Anstelle des Null-Objekt-Musters - das hat seine Verwendung - könnten Sie Situationen in Betracht ziehen, in denen das Null-Objekt ein Fehler ist.

Wenn die Ausnahme ausgelöst wird, überprüfen Sie die Stack-Ablaufverfolgung und gehen Sie den Fehler durch.




Null ist kein "Problem". Es ist ein wesentlicher Bestandteil eines complete Modellierungswerkzeugsatzes. Software zielt darauf ab, die Komplexität der Welt zu modellieren, und Null trägt ihre Last. Null bedeutet in Java und dergleichen "Keine Daten" oder "Unbekannt" . Daher ist es sinnvoll, für diese Zwecke Nullen zu verwenden. Ich ziehe das "Nullobjekt" -Muster nicht vor. Ich denke, es stellt sich das Problem „ Wer wird die Wächter bewachen “.
Wenn Sie mich fragen, wie meine Freundin heißt, sage ich Ihnen, dass ich keine Freundin habe. In der Java-Sprache gebe ich null zurück. Eine Alternative wäre, eine sinnvolle Ausnahme auszulösen, um auf ein Problem hinzuweisen, das nicht sein kann (oderSie möchten direkt dort gelöst werden und delegieren Sie sie an einen höheren Ort im Stapel, um den Benutzer erneut zu versuchen oder einen Datenzugriffsfehler zu melden.

  1. Für eine "unbekannte Frage" geben Sie "unbekannte Antwort" an. (Seien Sie nullsicher, wenn dies aus betriebswirtschaftlicher Sicht korrekt ist.) Wenn Argumente vor der Verwendung einmal vor einer Verwendung auf null überprüft werden, können mehrere Anrufer sie vor einem Anruf nicht überprüfen.

    public Photo getPhotoOfThePerson(Person person) {
        if (person == null)
            return null;
        // Grabbing some resources or intensive calculation
        // using person object anyhow.
    }
    

    Vorherige führt zu einem normalen Logikfluss, um kein Foto einer nicht existierenden Freundin aus meiner Fotobibliothek zu erhalten.

    getPhotoOfThePerson(me.getGirlfriend())
    

    Und es passt zu der neuen Java-API (wir freuen uns darauf)

    getPhotoByName(me.getGirlfriend()?.getName())
    

    Während es eher ein „normaler Geschäftsablauf“ ist, Fotos, die in der Datenbank gespeichert sind, für einige Personen nicht zu finden, habe ich in einigen anderen Fällen Paare wie unten verwendet

    public static MyEnum parseMyEnum(String value); // throws IllegalArgumentException
    public static MyEnum parseMyEnumOrNull(String value);
    

    Und verabscheuen Sie sich nicht <alt> + <shift> + <j>( tippen Sie Javadoc in Eclipse ein) und schreiben Sie drei zusätzliche Wörter für Ihre öffentliche API. Dies ist mehr als genug für alle, außer denen, die keine Dokumentation lesen.

    /**
     * @return photo or null
     */
    

    oder

    /**
     * @return photo, never null
     */
    
  2. Dies ist eher ein theoretischer Fall, und in den meisten Fällen sollten Sie die Java-sichere API (falls diese in weiteren 10 Jahren veröffentlicht wird) vorziehen, ist aber NullPointerExceptioneine Unterklasse von Exception. Es ist also eine Form Throwable, die auf Bedingungen hinweist, die eine vernünftige Anwendung möglicherweise einfangen möchte ( javadoc )! Um den ersten Vorteil von Ausnahmen zu nutzen und den Fehlerbehandlungscode von "regulärem" Code ( gemäß Java-Erstellern ) zu trennen , ist es wie für mich angebracht, zu fangen NullPointerException.

    public Photo getGirlfriendPhoto() {
        try {
            return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
        } catch (NullPointerException e) {
            return null;
        }
    }
    

    Fragen könnten aufkommen:

    F. Was ist, wenn getPhotoDataSource()null zurückgegeben wird?
    A. Es liegt an der Geschäftslogik. Wenn ich kein Fotoalbum finde, zeige ich Ihnen keine Fotos. Was ist, wenn appContext nicht initialisiert wird? Die Geschäftslogik dieser Methode macht das mit. Wenn die gleiche Logik strenger sein sollte und eine Ausnahme ausgelöst wird, ist dies Teil der Geschäftslogik, und die explizite Überprüfung auf null sollte verwendet werden (Fall 3). Die neue Java-Null-sichere API passt hier besser, um gezielt anzugeben, was impliziert und was nicht bedeutet, dass es im Falle von Programmierfehlern als ausfallsicher initialisiert werden soll.

    F. Redundanter Code könnte ausgeführt werden und unnötige Ressourcen könnten ergriffen werden.
    A: Es könnte geschehen, wenn Sie getPhotoByName()versuchen würden, eine Datenbankverbindung zu öffnen, PreparedStatementden Personennamen zuletzt als SQL-Parameter zu erstellen und zu verwenden. Der Ansatz für eine unbekannte Frage gibt hier eine unbekannte Antwort (Fall 1). Vor dem Zugriff auf Ressourcen sollte die Methode die Parameter überprüfen und bei Bedarf das Ergebnis "unbekannt" zurückgeben.

    F: Dieser Ansatz hat eine Leistungsstrafe aufgrund der versuchten Schließung.
    A. Software sollte zunächst leicht verständlich sein und modifiziert werden. Erst danach konnte über Leistung nachgedacht werden, und nur wenn nötig! und wo nötig ( source ) und viele andere).

    PS.Dieser Ansatz ist so vernünftig zu verwenden, da der separate Fehlerbehandlungscode vom Prinzip des "normalen" Codes an einigen Stellen angemessen ist. Betrachten Sie das nächste Beispiel:

    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        try {
            Result1 result1 = performSomeCalculation(predicate);
            Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
            Result3 result3 = performThirdCalculation(result2.getSomeProperty());
            Result4 result4 = performLastCalculation(result3.getSomeProperty());
            return result4.getSomeProperty();
        } catch (NullPointerException e) {
            return null;
        }
    }
    
    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        SomeValue result = null;
        if (predicate != null) {
            Result1 result1 = performSomeCalculation(predicate);
            if (result1 != null && result1.getSomeProperty() != null) {
                Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
                if (result2 != null && result2.getSomeProperty() != null) {
                    Result3 result3 = performThirdCalculation(result2.getSomeProperty());
                    if (result3 != null && result3.getSomeProperty() != null) {
                        Result4 result4 = performLastCalculation(result3.getSomeProperty());
                        if (result4 != null) {
                            result = result4.getSomeProperty();
                        }
                    }
                }
            }
        }
        return result;
    }
    

    PPS.Für diejenigen, die schnell absteigen (und nicht so schnell die Dokumentation lesen), möchte ich sagen, dass ich in meinem Leben noch nie eine Nullzeiger-Ausnahme (NPE) entdeckt habe. Diese Möglichkeit wurde jedoch von den Java-Erstellern absichtlich entworfen, da NPE eine Unterklasse von ist Exception. Wir haben einen Präzedenzfall in der Java-Geschichte, wenn dies nicht der Fall ThreadDeathist, Errorweil es sich tatsächlich um einen Anwendungsfehler handelt, sondern nur, weil es nicht beabsichtigt war, erwischt zu werden! Wie viel NPE passt, um Errorals zu sein ThreadDeath! Aber es ist nicht.

  3. Prüfen Sie, ob keine Daten vorhanden sind, nur wenn die Geschäftslogik dies impliziert.

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person != null) {
            person.setPhoneNumber(phoneNumber);
            dataSource.updatePerson(person);
        } else {
            Person = new Person(personId);
            person.setPhoneNumber(phoneNumber);
            dataSource.insertPerson(person);
        }
    }
    

    und

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person == null)
            throw new SomeReasonableUserException("What are you thinking about ???");
        person.setPhoneNumber(phoneNumber);
        dataSource.updatePerson(person);
    }
    

    Wenn appContext oder dataSource nicht initialisiert wird, wird die nicht behandelte Laufzeit von NullPointerException beendet und von Thread.defaultUncaughtExceptionHandler verarbeitet (damit Sie Ihren bevorzugten Protokollierer oder einen anderen Benachrichtigungsmechanismus definieren und verwenden können). Wenn nicht festgelegt, gibt ThreadGroup#uncaughtException Stacktrace an system err aus. Man sollte das Anwendungsfehlerprotokoll überwachen und das Jira-Problem für jede nicht behandelte Ausnahme öffnen, bei der es sich tatsächlich um Anwendungsfehler handelt. Der Programmierer sollte den Fehler irgendwo in der Initialisierung beheben.




Gemeinsames "Problem" in der Tat in Java.

Zuerst meine Gedanken dazu:

Ich denke, dass es schlecht ist, etwas zu "essen", wenn NULL übergeben wurde und NULL kein gültiger Wert ist. Wenn Sie die Methode nicht mit einem Fehler beenden, bedeutet dies, dass in Ihrer Methode nichts schiefgelaufen ist, was nicht der Fall ist. Dann geben Sie in diesem Fall wahrscheinlich Null zurück, und in der empfangenden Methode überprüfen Sie erneut nach Null, und es endet nie, und Sie erhalten das Ergebnis "Wenn! = Null" usw.

IMHO, null muss ein kritischer Fehler sein, der die weitere Ausführung verhindert (dh, wenn null kein gültiger Wert ist).

So löse ich dieses Problem:

Zuerst folge ich dieser Konvention:

  1. Alle öffentlichen Methoden / API prüfen ihre Argumente immer auf null
  2. Alle privaten Methoden prüfen nicht auf null, da es sich um kontrollierte Methoden handelt (lassen Sie die Ausnahme mit nullpointer aus, falls sie oben nicht behandelt wurde).
  3. Die einzigen anderen Methoden, die nicht auf Null prüfen, sind Dienstprogrammmethoden. Sie sind öffentlich, aber wenn Sie sie aus irgendeinem Grund anrufen, wissen Sie, welche Parameter Sie übergeben. Dies ist, als würde man versuchen, Wasser im Wasserkocher ohne Wasser zu kochen ...

Und schließlich lautet die erste Zeile der öffentlichen Methode im Code folgendermaßen:

ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();

Beachten Sie, dass addParam () self zurückgibt, sodass Sie weitere Parameter zur Überprüfung hinzufügen können.

Die Methode validate()wirft geprüft, ValidationExceptionwenn einer der Parameter null ist (aktiviert oder deaktiviert, ist eher ein Design- / Geschmacksproblem, aber mein ValidationExceptionwird geprüft).

void validate() throws ValidationException;

Die Nachricht enthält den folgenden Text, wenn beispielsweise "plans" null ist:

Msgstr " Ungültiger Argumentwert null für Parameter [plans] gefunden "

Wie Sie sehen, wird der zweite Wert in der addParam () - Methode (Zeichenfolge) für die Benutzermeldung benötigt, da Sie den übergebenen Variablennamen nicht ohne weiteres erkennen können, selbst wenn die Reflektion (sowieso nicht Gegenstand dieses Beitrags)

Und ja, wir wissen, dass wir jenseits dieser Linie keinen Wert mehr finden werden, also rufen wir einfach Methoden für diese Objekte auf.

Auf diese Weise ist der Code sauber, leicht zu pflegen und lesbar.




Zusätzlich zur Verwendung können assertSie Folgendes verwenden:

if (someobject == null) {
    // Handle null here then move on.
}

Das ist etwas besser als:

if (someobject != null) {
    .....
    .....



    .....
}



Guava, eine sehr nützliche Kernbibliothek von Google, verfügt über eine nette und nützliche API, um Nullen zu vermeiden. Ich finde Guava sehr hilfreich.

Wie im Wiki erklärt:

Optional<T>ist eine Möglichkeit, eine nullfähige T-Referenz durch einen Nicht-Nullwert zu ersetzen. Ein optionales Element kann entweder eine Nicht-Null-T-Referenz enthalten (in diesem Fall sagen wir, dass die Referenz "vorhanden" ist) oder es kann nichts enthalten (in diesem Fall sagen wir, dass die Referenz "nicht vorhanden" ist). Es wird nie gesagt, dass es "null" enthält.

Verwendungszweck:

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5



Ich mag Artikel von Nat Pryce. Hier sind die Links:

In den Artikeln gibt es auch einen Link zu einem Git-Repository für einen Java-Dateityp, den ich interessant finde, aber ich denke nicht, dass allein dies die Überprüfung des Code-Aufblasens verringern kann. Nach einigen Recherchen im Internet denke ich, dass ! = Null Code Bloat hauptsächlich durch sorgfältiges Design reduziert werden konnte.




Die beste Alternative für Java 8 oder neuer ist die Verwendung der OptionalKlasse.

Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);

Dies ist besonders praktisch für lange Ketten möglicher Nullwerte. Beispiel:

Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());

Beispiel zum Auslösen einer Ausnahme auf null:

Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);

Java 7 führte die Objects.requireNonNullMethode ein, die nützlich sein kann, wenn etwas auf Nicht-NULL-Wert geprüft werden soll. Beispiel:

String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();



Ich ignoriere die Antworten, die die Verwendung von Nullobjekten in jeder Situation suggerieren. Dieses Muster kann den Vertrag brechen und Probleme tiefer und tiefer vergraben, anstatt sie zu lösen, wobei nicht erwähnt wird, dass ein unsachgemäßer Gebrauch einen weiteren Stapel Boilerplate-Code erzeugt, der zukünftige Wartung erfordert.

Wenn etwas, das von einer Methode zurückgegeben wird, null sein kann und der aufrufende Code eine Entscheidung darüber treffen muss, sollte ein früherer Aufruf erfolgen, der den Status sicherstellt.

Denken Sie auch daran, dass das Null-Objekt-Muster bei Nichtbeachtung speicherhungrig ist. Zu diesem Zweck sollte die Instanz eines NullObjects von den Eigentümern gemeinsam genutzt werden und darf nicht für jeden dieser Objekte eine einzige Instanz sein.

Ich würde auch nicht empfehlen, dieses Muster zu verwenden, wenn der Typ eine primitive Typrepräsentation sein soll - wie mathematische Entitäten, die keine Skalare sind: Vektoren, Matrizen, komplexe Zahlen und POD-Objekte (Plain Old Data), die den Zustand enthalten sollen in Form von integrierten Java-Typen. Im letzteren Fall würden Sie Getter-Methoden mit beliebigen Ergebnissen aufrufen. Was sollte beispielsweise eine NullPerson.getName () -Methode zurückgeben?

Solche Fälle sollten in Betracht gezogen werden, um absurde Ergebnisse zu vermeiden.




Dies ist der häufigste Fehler, der bei den meisten Entwicklern aufgetreten ist.

Wir haben viele Möglichkeiten, damit umzugehen.

Ansatz 1:

org.apache.commons.lang.Validate //using apache framework

notNull (Objektobjekt, String-Nachricht)

Ansatz 2:

if(someObject!=null){ // simply checking against null
}

Ansatz 3:

@isNull @Nullable  // using annotation based validation

Ansatz 4:

// by writing static method and calling it across whereever we needed to check the validation

static <T> T isNull(someObject e){  
   if(e == null){
      throw new NullPointerException();
   }
   return e;
}



Related