576 Stimmen

IllegalArgumentException oder NullPointerException für einen Null-Parameter?

Ich habe eine einfache Setter-Methode für eine Eigenschaft und null ist für diese spezielle Immobilie nicht geeignet. Ich war in dieser Situation immer hin- und hergerissen: Sollte ich eine IllegalArgumentException oder eine NullPointerException ? Nach den Javadocs scheinen beide geeignet zu sein. Gibt es so etwas wie einen anerkannten Standard? Oder ist das einfach so, dass man das tun sollte, was man bevorzugt, und beides ist wirklich richtig?

49voto

Christopher Smith Punkte 5151

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

  • Le site NPE JavaDoc sagt ausdrücklich, "andere illegale Verwendungen des Null-Objekts" . Wenn es nur auf Situationen beschränkt wäre, in denen die Laufzeit auf eine Null stößt, obwohl dies nicht der Fall sein sollte, könnten alle derartigen Fälle viel prägnanter definiert werden.

  • Ich kann nichts dafür, wenn Sie das Falsche annehmen, aber unter der Annahme, dass die Kapselung ordnungsgemäß angewendet wird, sollte es Ihnen wirklich egal sein, ob eine Null unangemessen dereferenziert wurde, oder ob eine Methode eine unangemessene Null erkannt und eine Ausnahme ausgelöst hat.

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

    • Die Art des illegalen Vorgangs wird genauer beschrieben
    • Logik, die fälschlicherweise Nullen zulässt, unterscheidet sich in der Regel stark von Logik, die fälschlicherweise illegale Werte zulässt. Wenn ich zum Beispiel die von einem Benutzer eingegebenen Daten validiere und einen inakzeptablen Wert erhalte, liegt die Fehlerquelle beim Endbenutzer der Anwendung. Wenn ich eine Null erhalte, ist das ein Programmiererfehler.
    • Ungültige Werte können z. B. Stapelüberläufe, Speicherplatzmangel, Parsing-Ausnahmen usw. verursachen. In der Tat treten die meisten Fehler irgendwann als ungültiger Wert in einem Methodenaufruf auf. Aus diesem Grund sehe ich IAE eigentlich als die 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 Ausnahmen bei Syntaxfehlern, IndexOutOfBoundsException Authentifizierungsfehler, usw., usw.

Im Allgemeinen bin ich der Meinung, dass NPE viel geschmäht wird, weil es traditionell mit Code in Verbindung gebracht wird, der nicht den Fail-Fast-Prinzip . Dies und das Versäumnis des JDK, NPEs mit einem Meldungsstring zu versehen, hat zu einer starken negativen Stimmung geführt, die nicht gut begründet ist. Tatsächlich besteht der Unterschied zwischen NPE und IAE aus Sicht der Laufzeit nur im Namen. Je präziser der Name ist, desto mehr Klarheit erhält der Aufrufer.

22voto

Steve McLeod Punkte 50514

Es ist eine Frage wie im "Heiligen Krieg". Mit anderen Worten: Beide Alternativen sind gut, aber die Menschen werden ihre Präferenzen haben, die sie bis zum Tod verteidigen werden.

18voto

Jeremy Privett Punkte 4425

Wenn es sich um eine setter Methode und null übergeben wird, halte ich es für sinnvoller, eine IllegalArgumentException . A NullPointerException scheint in dem Fall sinnvoller zu sein, in dem Sie versuchen, die null .

Wenn Sie es also benutzen und es ist null , NullPointer . Wenn es durchgereicht wird und es ist null , IllegalArgument .

10voto

Brian T. Grant Punkte 187

Apache Commons Lang hat eine NullArgumentException die eine Reihe der hier besprochenen Dinge tut: Sie erweitert IllegalArgumentException und ihr einziger Konstruktor nimmt den Namen des Arguments, das nicht null sein sollte.

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

8voto

Ben Seidel Punkte 414

Da es sich um eine subjektive Frage handelt, sollte sie geschlossen werden, aber sie ist noch offen:

Dies ist Teil der internen Politik, die bei meiner früheren Arbeitsstelle angewandt wurde, und es hat wirklich gut funktioniert. Ich kann mich nicht mehr an den genauen Wortlaut erinnern. Es ist erwähnenswert, dass sie keine angekreuzten Ausnahmen verwendet haben, aber das würde den Rahmen der Frage sprengen. Die ungeprüften Ausnahmen, die sie verwendeten, fielen in 3 Hauptkategorien.

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

IllegalArgumentException: Wird ausgelöst, wenn ein Argument einer Funktion nicht mit der öffentlichen Dokumentation übereinstimmt, so dass der Fehler anhand der übergebenen Argumente identifiziert und beschrieben werden kann. Die Situation der OP würde in diese Kategorie fallen.

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

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

Wie ich schon sagte, funktioniert dieses System wirklich gut, und es brauchte jemanden, der erklärt, warum es diesen Unterschied gibt: "Je nach Art des Fehlers können Sie ganz einfach herausfinden, was zu tun ist. Selbst wenn Sie nicht herausfinden können, was schief gelaufen ist, können Sie herausfinden, wo Sie den Fehler abfangen und zusätzliche Fehlerbehebungsinformationen erstellen können."

NullPointerException: Behandeln Sie den Null-Fall oder fügen Sie eine Behauptung ein, damit die NPE nicht ausgelöst wird. Wenn Sie eine Behauptung einfügen, handelt es sich nur um einen der beiden anderen Typen. Wenn möglich, fahren Sie mit der Fehlersuche fort, als ob die Behauptung von Anfang an vorhanden gewesen wäre.

IllegalArgumentException: Sie haben einen Fehler an Ihrer Aufrufstelle. Wenn die übergebenen Werte aus einer anderen Funktion stammen, finden Sie heraus, warum Sie einen falschen Wert erhalten. Wenn Sie eines Ihrer Argumente übergeben, wandern die Fehlerprüfungen den Aufrufstapel hinauf, bis Sie die Funktion finden, die nicht das zurückgibt, was Sie erwarten.

IllegalStateException: Sie haben Ihre Funktionen nicht in der richtigen Reihenfolge aufgerufen. Wenn Sie eines Ihrer Argumente verwenden, überprüfen Sie diese und werfen eine IllegalArgumentException, die das Problem beschreibt. Sie können dann die Wangen auf dem Stapel weitergeben, bis Sie das Problem finden.

Wie auch immer, sein Punkt war, dass Sie nur die IllegalArgumentAssertions auf den Stapel kopieren können. Es gibt keine Möglichkeit, die IllegalStateExceptions oder NullPointerExceptions auf dem Stack weiterzugeben, weil sie etwas mit Ihrer Funktion zu tun haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X