Frage

Ich habe eine einfache Setter-Methode für eine Eigenschaft und null ist für diese bestimmte Immobilie nicht geeignet.Ich war immer in dieser Situation hin- und hergerissen:soll ich eine werfen IllegalArgumentException, oder ein NullPointerException?Aus den Javadocs scheint beides angemessen zu sein.Gibt es eine Art verständlichen Standard?Oder ist dies nur eines dieser Dinge, bei denen Sie tun und lassen sollten, was Sie möchten, und beides ist wirklich richtig?

War es hilfreich?

Lösung

Es scheint wie ein IllegalArgumentException ist gefragt, wenn Sie nicht wollen null ein zulässiger Wert sein, und der NullPointerException würde geworfen werden, wenn Sie es versuchen würden verwenden eine Variable, die sich als solche herausstellt null.

Andere Tipps

Sie sollten verwenden IllegalArgumentException (IAE), nicht NullPointerException (NPE) aus folgenden Gründen:

Zuerst die NPE JavaDoc listet explizit die Fälle auf, in denen NPE angemessen ist.Beachten Sie, dass alle geworfen werden durch die Laufzeit Wann null wird unangemessen verwendet.Im Gegensatz dazu ist die IAE JavaDoc könnte nicht klarer sein:"Um anzuzeigen, dass eine Methode ein illegales oder unangemessenes Argument verabschiedet wurde." Ja, das bist du!

Zweitens: Was gehen Sie davon aus, wenn Sie einen NPE in einem Stack-Trace sehen?Wahrscheinlich hat jemand a dereferenziert null.Wenn Sie IAE sehen, gehen Sie davon aus, dass der Aufrufer der Methode oben im Stapel einen unzulässigen Wert übergeben hat.Auch hier ist die letztere Annahme wahr, die erstere ist irreführend.

Drittens: Da IAE eindeutig für die Validierung von Parametern konzipiert ist, müssen Sie davon ausgehen, dass es die Standardausnahme ist. Warum sollten Sie sich stattdessen für NPE entscheiden?Sicherlich nicht wegen unterschiedlichem Verhalten – erwarten Sie wirklich, dass Aufrufcode NPEs getrennt von IAE abfängt und dadurch etwas anderes tut?Versuchen Sie, eine spezifischere Fehlermeldung zu übermitteln?Sie können dies aber trotzdem im Ausnahmemeldungstext tun, wie Sie es auch bei allen anderen falschen Parametern tun sollten.

Viertens sind alle anderen falschen Parameterdaten IAE. Warum also nicht konsistent sein?Warum ist das illegal? null ist so besonders, dass es eine gesonderte Ausnahme von allen anderen Arten illegaler Argumente verdient?

Abschließend akzeptiere ich das Argument anderer Antworten, dass Teile der Java-API NPE auf diese Weise verwenden.Allerdings ist die Java-API mit allem, von Ausnahmetypen bis hin zu Namenskonventionen, inkonsistent, daher ist meiner Meinung nach das bloße blinde Kopieren (Ihres Lieblingsteils) der Java-API kein gutes Argument, um diese anderen Überlegungen zu übertrumpfen.

Der Standard besteht darin, das zu werfen NullPointerException.Das allgemein unfehlbare „Effective Java“ erörtert dies kurz in Punkt 42 (erste Ausgabe), Punkt 60 (zweite Ausgabe) oder Punkt 72 (dritte Ausgabe) „Bevorzugen Sie die Verwendung von Standardausnahmen“:

"Möglicherweise sind alle fehlerhaften Methodenauffälle auf ein illegales Argument oder einen illegalen Zustand zurückzuführen, aber andere Ausnahmen werden für bestimmte Arten von illegalen Argumenten und Staaten standardmäßig verwendet.Wenn ein Anrufer in einem Parameter, für den Nullwerte verboten sind, Null übergibt, schreibt die Konvention vor, dass NullPointerexception eher als illegalArgumentException ausgeworfen wird. "

Ich war voll und ganz für das Werfen IllegalArgumentException für Nullparameter, bis ich heute das bemerkt habe java.util.Objects.requireNonNull Methode in Java 7.Mit dieser Methode, anstatt Folgendes zu tun:

if (param == null) {
    throw new IllegalArgumentException("param cannot be null.");
}

du kannst tun:

Objects.requireNonNull(param);

und es wird ein werfen NullPointerException wenn der Parameter, den Sie übergeben, derselbe ist null.

Angesichts der Tatsache, dass diese Methode genau in der Mitte liegt java.util Ich halte seine Existenz für einen ziemlich starken Hinweis auf das Werfen NullPointerException ist „die Java-Methode, Dinge zu erledigen“.

Ich denke, ich bin auf jeden Fall entschieden.

Beachten Sie, dass die Argumente zum harten Debuggen falsch sind, da Sie natürlich eine Nachricht senden können NullPointerException sagen, was null war und warum es nicht null sein sollte.Genauso wie mit IllegalArgumentException.

Ein zusätzlicher Vorteil von NullPointerException ist, dass Sie in hochleistungskritischem Code auf eine explizite Prüfung auf Null (und a) verzichten könnten NullPointerException mit einer freundlichen Fehlermeldung) und verlassen Sie sich einfach auf die NullPointerException Sie erhalten automatisch, wenn Sie eine Methode für den Nullparameter aufrufen.Vorausgesetzt, Sie rufen eine Methode schnell auf (d. h.scheitern schnell), dann haben Sie im Wesentlichen den gleichen Effekt, nur nicht ganz so benutzerfreundlich für den Entwickler.In den meisten Fällen ist es wahrscheinlich besser, dies explizit zu überprüfen und eine nützliche Meldung auszulösen, die angibt, welcher Parameter null war. Es ist jedoch schön, die Möglichkeit zu haben, dies zu ändern, wenn die Leistung dies erfordert, ohne den veröffentlichten Vertrag der Methode/des Konstruktors zu verletzen.

Ich tendiere dazu, dem Design von JDK-Bibliotheken zu folgen, insbesondere von Sammlungen und Parallelität (Joshua Bloch, Doug Lea, diese Leute wissen, wie man solide APIs entwirft).Wie auch immer, viele APIs im JDK werden proaktiv ausgelöst NullPointerException.

Zum Beispiel das Javadoc für Map.containsKey Zustände:

@throws nullPointerexception Wenn der Schlüssel null ist und diese Karte keine Nullschlüssel (optional) zulässt.

Es ist vollkommen berechtigt, Ihre eigene NPE zu werfen.Die Konvention besteht darin, den Parameternamen, der null war, in die Ausnahmemeldung aufzunehmen.

Das Muster lautet:

public void someMethod(Object mustNotBeNull) {  
    if (mustNotBeNull == null) {  
        throw new NullPointerException("mustNotBeNull must not be null");  
    }  
}

Was auch immer Sie tun: Lassen Sie nicht zu, dass ein fehlerhafter Wert festgelegt wird, und lösen Sie später eine Ausnahme aus, wenn anderer Code versucht, ihn zu verwenden.Das macht das Debuggen zu einem Albtraum.Sie sollten stets dem „Fail-Fast“-Prinzip folgen.

Ich habe für Jason Cohens Argument gestimmt, weil es gut dargelegt wurde.Lassen Sie mich es Schritt für Schritt zerlegen.;-)

  • Der NPE JavaDoc sagt ausdrücklich, „Andere illegale Verwendungen des Nullobjekts“.Wenn es nur auf Situationen beschränkt wäre, in denen die Laufzeit auf einen Nullwert trifft, obwohl dies nicht der Fall sein sollte, könnten alle diese Fälle viel prägnanter definiert werden.

  • Ich kann nicht anders, wenn Sie das Falsche annehmen, aber vorausgesetzt, die Kapselung wird ordnungsgemäß angewendet, sollte es Ihnen wirklich egal sein oder auffallen, ob eine Null unangemessen dereferenziert wurde oder nicht.ob eine Methode einen unangemessenen Nullwert erkannt und eine Ausnahme ausgelöst hat.

  • Ich würde wählen NPE über IAE aus mehreren Gründen

    • Es wird genauer auf die Art der illegalen Operation eingegangen
    • Logik, die fälschlicherweise Nullen zulässt, unterscheidet sich tendenziell stark von Logik, die fälschlicherweise unzulässige Werte zulässt.Wenn ich beispielsweise die von einem Benutzer eingegebenen Daten validiere und einen Wert erhalte, der inakzeptabel ist, liegt die Fehlerquelle beim Endbenutzer der Anwendung.Wenn ich eine Null erhalte, ist das ein Programmierfehler.
    • Ungültige Werte können zu Stapelüberläufen, Speicherfehlern, Parsing-Ausnahmen usw. führen.Tatsächlich treten die meisten Fehler im Allgemeinen irgendwann als ungültiger Wert in einem Methodenaufruf auf.Aus diesem Grund sehe ich IAE als eigentlich das ALLGEMEINES aller Ausnahmen unter RuntimeException.
  • Tatsächlich können andere ungültige Argumente zu allen möglichen anderen Ausnahmen führen. UnknownHostException, FileNotFoundException, eine Vielzahl von Syntaxfehlerausnahmen, IndexOutOfBoundsException, Authentifizierungsfehler usw. usw.

Im Allgemeinen bin ich der Meinung, dass NPE stark verunglimpft wird, da es traditionell mit Code in Verbindung gebracht wird, der sich nicht an die Vorschriften hält Fail-Fast-Prinzip.Dies und das Versäumnis des JDK, NPEs mit einer Nachrichtenzeichenfolge zu füllen, hat wirklich zu einer starken negativen Stimmung geführt, die nicht begründet ist.Tatsächlich liegt der Unterschied zwischen NPE und IAE aus Sicht der Laufzeit ausschließlich im Namen.Aus dieser Perspektive gilt: Je präziser Sie den Namen angeben, desto mehr Klarheit geben Sie dem Anrufer.

Es ist eine Frage im Stil des „Heiligen Krieges“.Mit anderen Worten: Beide Alternativen sind gut, aber die Menschen werden ihre Vorlieben haben, die sie bis zum Tod verteidigen werden.

Wenn es ein ist setter Methode und null wird daran übergeben, ich denke, es wäre sinnvoller, eine zu werfen IllegalArgumentException.A NullPointerException scheint sinnvoller zu sein, wenn Sie versuchen, das tatsächlich zu verwenden null.

Also, wenn Sie es verwenden und es ist null, NullPointer.Wenn es weitergegeben wird und es ist null, IllegalArgument.

Apache Commons Lang hat eine NullArgumentException das bewirkt eine Reihe der hier besprochenen Dinge:Es erweitert IllegalArgumentException und sein einziger Konstruktor übernimmt den Namen des Arguments, das ungleich Null sein sollte.

Obwohl ich der Meinung bin, dass das Auslösen von so etwas wie einer NullArgumentException oder IllegalArgumentException die außergewöhnlichen Umstände genauer beschreibt, haben meine Kollegen und ich beschlossen, Blochs Rat zu diesem Thema zu befolgen.

Ich kann dem Gesagten nur zustimmen.Scheitern Sie früh, scheitern Sie schnell.Ziemlich gutes Ausnahme-Mantra.

Die Frage, welche Ausnahme ausgelöst werden soll, ist größtenteils eine Frage des persönlichen Geschmacks.Meiner Meinung nach scheint IllegalArgumentException spezifischer zu sein als die Verwendung einer NPE, da sie mir sagt, dass das Problem bei einem Argument lag, das ich an die Methode übergeben habe, und nicht bei einem Wert, der möglicherweise während der Ausführung der Methode generiert wurde.

Meine 2 Cent

Die akzeptierte Praxis, wenn man das verwendet IllegalArgumentException( String-Nachricht) einen Parameter für ungültig erklären und so viele Details wie möglich angeben ...Wenn also festgestellt wurde, dass ein Parameter null ist, während eine Ausnahme ungleich null ist, würden Sie etwa Folgendes tun:

if( variable == null )
    throw new IllegalArgumentException("The object 'variable' cannot be null");

Sie haben praktisch keinen Grund, die „NullPointerException“ implizit zu verwenden.Die NullPointerException ist eine Ausnahme, die von der Java Virtual Machine ausgelöst wird, wenn Sie versuchen, Code auf einer Nullreferenz auszuführen (z. B toString()).

Tatsächlich ist die Frage des Auslösens von IllegalArgumentException oder NullPointerException meiner bescheidenen Ansicht nach nur ein „heiliger Krieg“ für eine Minderheit mit unvollständigem Verständnis der Ausnahmebehandlung in Java.Im Allgemeinen sind die Regeln einfach und wie folgt:

  • Verstöße gegen Argumenteinschränkungen müssen so schnell wie möglich angezeigt werden (-> fast fail), um illegale Zustände zu vermeiden, die viel schwieriger zu debuggen sind
  • Im Falle eines ungültigen Nullzeigers aus irgendeinem Grund wird eine NullPointerException ausgelöst
  • Im Falle eines unzulässigen Array-/Sammlungsindex wird ArrayIndexOutOfBounds ausgelöst
  • Im Falle einer negativen Array-/Sammlungsgröße wird eine NegativeArraySizeException ausgelöst
  • Im Falle eines illegalen Arguments, das oben nicht abgedeckt ist und für das Sie keinen anderen, spezifischeren Ausnahmetyp haben, werfen Sie IllegalArgumentException als Papierkorb
  • Im Falle einer Einschränkungsverletzung INNERHALB EINES FELDes, die aus einem triftigen Grund nicht durch Fast Fail vermieden werden konnte, fangen Sie die Ausnahme ab und lösen Sie sie erneut als IllegalStateException oder eine spezifischere geprüfte Ausnahme aus.Lassen Sie in diesem Fall niemals die ursprüngliche NullPointerException, ArrayIndexOutOfBounds usw. passieren!

Es gibt mindestens drei sehr gute Gründe, die dagegen sprechen, alle Arten von Verstößen gegen Argumenteinschränkungen auf IllegalArgumentException abzubilden, wobei der dritte wahrscheinlich so schwerwiegend ist, dass er die Praxis als schlechten Stil kennzeichnet:

(1) Ein Programmierer kann nicht mit Sicherheit davon ausgehen, dass alle Fälle von Verstößen gegen die Argumentbeschränkung zu einer IllegalArgumentException führen, da die große Mehrheit der Standardklassen diese Ausnahme eher als Papierkorb verwendet, wenn keine spezifischere Art von Ausnahme verfügbar ist.Der Versuch, alle Fälle von Verstößen gegen Argumenteinschränkungen IllegalArgumentException in Ihrer API zuzuordnen, führt nur zu Frustration für Programmierer bei der Verwendung Ihrer Klassen, da die Standardbibliotheken meist anderen Regeln folgen, die gegen Ihre Regeln verstoßen, und die meisten Ihrer API-Benutzer werden sie auch verwenden!

(2) Die Zuordnung der Ausnahmen führt tatsächlich zu einer anderen Art von Anomalie, die durch Einzelvererbung verursacht wird:Alle Java-Ausnahmen sind Klassen und unterstützen daher nur die Einzelvererbung.Daher gibt es keine Möglichkeit, eine Ausnahme zu erstellen, die wirklich sowohl eine NullPointerException als auch eine IllegalArgumentException ist, da Unterklassen nur von der einen oder der anderen erben können.Das Auslösen einer IllegalArgumentException im Falle eines Nullarguments erschwert es API-Benutzern daher, zwischen Problemen zu unterscheiden, wenn ein Programm versucht, das Problem programmgesteuert zu beheben, indem es beispielsweise Standardwerte in eine Aufrufwiederholung einfügt!

(3) Beim Mapping besteht tatsächlich die Gefahr der Fehlermaskierung:Um Verstöße gegen die Argumentbeschränkung in IllegalArgumentException abzubilden, müssen Sie in jeder Methode, die über eingeschränkte Argumente verfügt, einen äußeren Try-Catch codieren.Es kommt jedoch nicht in Frage, RuntimeException einfach in diesem Catch-Block abzufangen, da dadurch das Risiko besteht, dokumentierte RuntimeExceptions, die von in Ihnen verwendeten Liberty-Methoden ausgelöst werden, in IllegalArgumentException abzubilden, selbst wenn sie nicht durch Verstöße gegen Argumenteinschränkungen verursacht werden.Sie müssen also sehr genau sein, aber selbst dieser Aufwand schützt Sie nicht vor dem Fall, dass Sie versehentlich eine undokumentierte Laufzeitausnahme einer anderen API zuordnen (z. B.ein Fehler) in eine IllegalArgumentException Ihrer API.Selbst bei der sorgfältigsten Zuordnung besteht daher die Gefahr, dass Programmierfehler anderer Bibliotheksersteller als Verstöße gegen die Argumenteinschränkungen der Benutzer Ihrer Methode maskiert werden, was einfach ein lächerliches Verhalten ist!

Bei der Standardpraxis hingegen bleiben die Regeln einfach und Ausnahmeursachen bleiben unmaskiert und spezifisch.Auch für den Methodenaufrufer sind die Regeln einfach:- Wenn Sie auf eine dokumentierte Laufzeitausnahme von jeglicher Art stoßen, weil Sie einen illegalen Wert bestanden haben, wiederholen Sie den Aufruf entweder mit einem Standard (für diese spezifischen Ausnahmen sind negativ) oder korrigieren Es ist nicht dokumentiert, dass für eine bestimmte Argumente ein Fehlerbericht an die Macher der Methode vorliegt, um sicherzustellen, dass entweder der Code oder deren Dokumentation festgelegt wird.

Im Allgemeinen sollte ein Entwickler niemals wirft eine NullPointerException aus.Diese Ausnahme wird von der Laufzeit ausgelöst, wenn Code versucht, eine Variable zu dereferenzieren, deren Wert null ist.Wenn Ihre Methode daher NULL explizit verbieten möchte, anstatt dass ein NULL-Wert zufällig eine NullPointerException auslöst, sollten Sie daher eine IllegalArgumentException auslösen.

Eine Ausnahme auslösen, die exklusiv für ist null Argumente (ob NullPointerException oder ein benutzerdefinierter Typ) automatisiert null Tests zuverlässiger.Dieses automatisierte Testen kann mit Reflektion und einer Reihe von Standardwerten durchgeführt werden, wie in Guave'S NullPointerTester.Zum Beispiel, NullPointerTester würde versuchen, die folgende Methode aufzurufen ...

Foo(String string, List<?> list) {
  checkArgument(string.length() > 0);
  // missing null check for list!
  this.string = string;
  this.list = list;
}

...mit zwei Listen von Argumenten: "", null Und null, ImmutableList.of().Es würde testen, ob jeder dieser Aufrufe das erwartete Ergebnis auslöst NullPointerException.Für diese Implementierung ist die Übergabe von a null Liste tut es nicht produzieren NullPointerException.Es entsteht jedoch zufällig ein IllegalArgumentException Weil NullPointerTester verwendet zufällig eine Standardzeichenfolge von "".Wenn NullPointerTester erwartet nur NullPointerException für null Werte, es fängt den Fehler.Wenn es erwartet IllegalArgumentException, es verfehlt es.

Als subjektive Frage sollte dies geschlossen werden, da sie jedoch noch offen ist:

Dies ist Teil der internen Richtlinie an meinem vorherigen Arbeitsplatz und hat wirklich gut funktioniert.Das ist alles aus dem Gedächtnis, daher kann ich mich nicht an den genauen Wortlaut erinnern.Es ist erwähnenswert, dass keine geprüften Ausnahmen verwendet wurden, aber das würde den Rahmen der Frage sprengen.Die ungeprüften Ausnahmen, die sie verwendeten, ließen sich in drei Hauptkategorien einteilen.

NullPointerException:Nicht absichtlich werfen.NPEs dürfen nur von der VM ausgelöst werden, wenn eine Nullreferenz dereferenziert wird.Es sind alle möglichen Anstrengungen zu unternehmen, um sicherzustellen, dass diese niemals geworfen werden.@Nullable und @NotNull sollten in Verbindung mit Code-Analysetools verwendet werden, um diese Fehler zu finden.

IllegalArgumentException:Wird ausgelöst, wenn ein Argument für eine Funktion nicht der öffentlichen Dokumentation entspricht, sodass der Fehler anhand der übergebenen Argumente identifiziert und beschrieben werden kann.Die Situation des OP würde in diese Kategorie fallen.

Illegale staatliche Ausnahme:Wird ausgelöst, wenn eine Funktion aufgerufen wird und ihre Argumente zum Zeitpunkt ihrer Übergabe entweder unerwartet sind oder mit dem Status des Objekts, zu dem die Methode gehört, nicht kompatibel sind.

Beispielsweise gab es zwei interne Versionen der IndexOutOfBoundsException, die in Dingen mit einer Länge verwendet wurden.Eine Unterklasse von IllegalStateException, die verwendet wird, wenn der Index größer als die Länge war.Die andere ist eine Unterklasse von IllegalArgumentException, die verwendet wird, wenn der Index negativ war.Dies lag daran, dass Sie dem Objekt weitere Elemente hinzufügen könnten und das Argument gültig wäre, während eine negative Zahl niemals gültig ist.

Wie gesagt, dieses System funktioniert wirklich gut und es bedurfte einer Erklärung, warum es diesen Unterschied gibt:„Abhängig von der Art des Fehlers ist es für Sie ganz einfach, herauszufinden, was zu tun ist.Selbst wenn Sie nicht wirklich herausfinden können, was schief gelaufen ist, können Sie herausfinden, wo dieser Fehler abgefangen werden kann, und zusätzliche Debugging-Informationen erstellen.“

NullPointerException:Behandeln Sie den Null-Fall oder fügen Sie eine Behauptung ein, damit die NPE nicht ausgelöst wird.Wenn Sie eine Behauptung eingeben, handelt es sich nur um einen der beiden anderen Typen.Wenn möglich, führen Sie das Debuggen so fort, als ob die Behauptung überhaupt vorhanden wäre.

IllegalArgumentException:An Ihrer Anrufstelle stimmt etwas nicht.Wenn die übergebenen Werte von einer anderen Funktion stammen, finden Sie heraus, warum Sie einen falschen Wert erhalten.Wenn Sie eines Ihrer Argumente weitergeben, überprüft der Fehler den Aufrufstapel, bis Sie die Funktion finden, die nicht das zurückgibt, was Sie erwarten.

Illegale staatliche Ausnahme:Sie haben Ihre Funktionen nicht in der richtigen Reihenfolge aufgerufen.Wenn Sie eines Ihrer Argumente verwenden, überprüfen Sie es und lösen Sie eine IllegalArgumentException aus, die das Problem beschreibt.Anschließend können Sie die Wangen gegen den Stapel ausbreiten, bis Sie das Problem gefunden haben.

Sein Punkt war jedenfalls, dass man nur die IllegalArgumentAssertions auf den Stapel kopieren kann.Es gibt für Sie keine Möglichkeit, die IllegalStateExceptions oder NullPointerExceptions im Stapel weiterzugeben, da sie etwas mit Ihrer Funktion zu tun haben.

Ich wollte Null-Argumente von anderen illegalen Argumenten unterscheiden und habe daher eine Ausnahme von IAE mit dem Namen NullArgumentException abgeleitet.Ohne die Ausnahmemeldung überhaupt lesen zu müssen, weiß ich, dass ein Nullargument an eine Methode übergeben wurde, und durch das Lesen der Nachricht finde ich heraus, welches Argument null war.Ich fange die NullArgumentException immer noch mit einem IAE-Handler ab, aber in meinen Protokollen kann ich den Unterschied schnell erkennen.

die Dichotomie...Überschneiden sie sich nicht?Nur nicht überlappende Teile eines Ganzen können eine Dichotomie ergeben.Wie ich es sehe:

throw new IllegalArgumentException(new NullPointerException(NULL_ARGUMENT_IN_METHOD_BAD_BOY_BAD));

Einige Sammlungen gehen davon aus null wird mit abgelehnt NullPointerException statt IllegalArgumentException.Wenn Sie beispielsweise einen Satz vergleichen, der Folgendes enthält: null zu einer Menge, die ablehnt null, der erste Satz wird anrufen containsAll auf der anderen Seite und fange es NullPointerException -- aber nicht IllegalArgumentException.(Ich schaue mir die Implementierung von an AbstractSet.equals.)

Man könnte vernünftigerweise argumentieren, dass die Verwendung ungeprüfter Ausnahmen auf diese Weise ein Antimuster ist, nämlich das Vergleichen von Sammlungen, die enthalten null zu Sammlungen, die nicht enthalten können null ist wirklich ein wahrscheinlicher Fehler sollen eine Ausnahme erzeugen oder diese setzen null in einer Sammlung überhaupt ist eine schlechte Idee.Allerdings, es sei denn, Sie sind bereit, das zu sagen equals Sollte in einem solchen Fall eine Ausnahme ausgelöst werden, müssen Sie sich daran erinnern NullPointerException ist unter bestimmten Umständen erforderlich, unter anderen jedoch nicht.(„IAE vor NPE außer nach ‚c‘ ...“)

NullPointerException wird ausgelöst, wenn versucht wird, auf ein Objekt mit einer Referenzvariablen zuzugreifen, deren aktueller Wert null ist

IllegalArgumentException wird ausgelöst, wenn eine Methode ein Argument empfängt, das anders formatiert ist als von der Methode erwartet

Gemäß Ihrem Szenario, IllegalArgumentException ist die beste Wahl, weil null ist kein gültiger Wert für Ihre Immobilie.

Im Idealfall sollten keine Laufzeitausnahmen ausgelöst werden.Für Ihr Szenario sollte eine geprüfte Ausnahme (Geschäftsausnahme) erstellt werden.Denn wenn eine dieser Ausnahmen ausgelöst und protokolliert wird, führt dies den Entwickler beim Durchsuchen der Protokolle in die Irre.Stattdessen lösen geschäftliche Ausnahmen diese Panik nicht aus und werden bei der Fehlerbehebung in Protokollen normalerweise ignoriert.

Die Definitionen aus den Links zu den beiden oben genannten Ausnahmen sind illegalArgumentException:Wird ausgelöst, um anzuzeigen, dass einer Methode ein illegales oder unangemessenes Argument übergeben wurde.NullPointerException:Wird ausgelöst, wenn eine Anwendung versucht, null zu verwenden, wenn ein Objekt erforderlich ist.

Der große Unterschied besteht darin, dass die IllegalArgumentException verwendet werden soll, wenn überprüft wird, ob ein Argument für eine Methode gültig ist.NullPointerException soll immer dann verwendet werden, wenn ein Objekt „verwendet“ wird, obwohl es null ist.

Ich hoffe, das hilft, die beiden ins rechte Licht zu rücken.

Wenn es sich um einen „Setter“ handelt oder irgendwo, wo ich später ein Mitglied benötige, verwende ich tendenziell IllegalArgumentException.

Wenn es sich um etwas handelt, das ich gerade in der Methode verwenden (dereferenzieren) werde, löse ich proaktiv eine NullPointerException aus.Das gefällt mir besser, als es der Laufzeitumgebung zu überlassen, da ich eine hilfreiche Nachricht bereitstellen kann (anscheinend könnte die Laufzeitumgebung dies auch tun, aber das ist eine Schimpferei für einen anderen Tag).

Wenn ich eine Methode überschreibe, verwende ich alles, was die überschriebene Methode verwendet.

Sie sollten eine IllegalArgumentException auslösen, da dies dem Programmierer klar macht, dass er etwas Ungültiges getan hat.Entwickler sind es so gewohnt, dass NPE von der VM ausgelöst wird, dass jeder Programmierer seinen Fehler nicht sofort erkennt und anfängt, sich wahllos umzusehen, oder, schlimmer noch, Ihrem Code die Schuld gibt, dass er „fehlerhaft“ ist.

In diesem Fall übermittelt IllegalArgumentException dem Benutzer, der Ihre API verwendet, klare Informationen darüber, dass „ nicht null sein sollte“.Wie andere Forumbenutzer darauf hingewiesen haben, können Sie NPE verwenden, wenn Sie möchten, solange Sie dem Benutzer mithilfe Ihrer API die richtigen Informationen übermitteln.

GaryF und Tweakt haben Referenzen zu „Effective Java“ (auf die ich schwöre) entfernt, die die Verwendung von NPE empfehlen.Und wenn Sie sich ansehen, wie andere gute APIs aufgebaut sind, können Sie am besten erkennen, wie Sie Ihre API aufbauen.

Ein weiteres gutes Beispiel ist ein Blick auf die Spring-APIs.Beispielsweise verfügt org.springframework.beans.BeanUtils.instantiateClass(Constructor ctor, Object[] args) über die Zeile Assert.notNull(ctor, „Constructor darf nicht null sein“).Die Methode org.springframework.util.Assert.notNull(Object object, String message) prüft, ob das übergebene Argument (Objekt) null ist, und wenn dies der Fall ist, löst sie eine neue IllegalArgumentException(message) aus, die dann in der Organisation abgefangen wird. springframework.beans.BeanUtils.instantiateClass(...)-Methode.

Wenn Sie sich dafür entscheiden, eine NPE auszulösen und das Argument in Ihrer Methode verwenden, kann es überflüssig und teuer sein, explizit nach einer Null zu suchen.Ich denke, die VM erledigt das bereits für Sie.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top