Letzte Woche hatten wir einen heftigen Streit über den Umgang mit Nullen in der Serviceschicht unserer Anwendung. Die Frage ist im .NET-Kontext, wird aber in Java und vielen anderen Technologien gleich sein.
Die Frage war: Sollten Sie immer nach Nullen suchen und sicherstellen, dass Ihr Code funktioniert, egal was passiert, oder eine Ausnahme auslösen, wenn eine Null unerwartet empfangen wird?
Auf der einen Seite ist das Prüfen auf null, wenn Sie es nicht erwarten (dh wenn Sie keine Benutzeroberfläche haben, um damit umzugehen), meiner Meinung nach dasselbe wie das Schreiben eines try-Blocks mit leerem catch. Sie verstecken nur einen Fehler. Der Fehler könnte sein, dass sich etwas im Code geändert hat und null nun ein erwarteter Wert ist, oder es liegt ein anderer Fehler vor und die falsche ID wird an die Methode übergeben.
Andererseits kann die Überprüfung auf Nullen im Allgemeinen eine gute Gewohnheit sein. Darüber hinaus funktioniert die Anwendung bei einer Überprüfung möglicherweise weiterhin, wobei nur ein kleiner Teil der Funktionalität keine Auswirkung hat. Dann könnte der Kunde einen kleinen Fehler wie "Kommentar kann nicht gelöscht werden" melden, anstatt einen viel schwerwiegenderen Fehler wie "Seite X kann nicht geöffnet werden".
Welcher Praxis folgen Sie und was sind Ihre Argumente für oder gegen einen der beiden Ansätze?
Aktualisieren:
Ich möchte einige Details zu unserem speziellen Fall hinzufügen. Wir haben einige Objekte aus der Datenbank abgerufen und sie bearbeitet (z. B. eine Sammlung erstellen). Der Entwickler, der den Code geschrieben hat, hat nicht damit gerechnet, dass das Objekt null sein könnte, sodass er keine Überprüfungen vorgenommen hat. Beim Laden der Seite ist ein Fehler aufgetreten, und die gesamte Seite wurde nicht geladen.
In diesem Fall hätte natürlich eine Überprüfung durchgeführt werden müssen. Dann haben wir uns darüber gestritten, ob jedes Objekt, das verarbeitet wird, überprüft werden soll, auch wenn nicht erwartet wird, dass es fehlt, und ob die eventuelle Verarbeitung im Hintergrund abgebrochen werden soll.
Der hypothetische Vorteil wäre, dass die Seite weiterhin funktioniert. Überlegen Sie sich Suchergebnisse zu Stack Exchange in verschiedenen Gruppen (Benutzer, Kommentare, Fragen). Die Methode könnte nach null suchen und die Verarbeitung von Benutzern abbrechen (was aufgrund eines Fehlers null ist), aber die Abschnitte "Kommentare" und "Fragen" zurückgeben. Die Seite würde weiterhin funktionieren, außer dass der Abschnitt "Benutzer" fehlen wird (was ein Fehler ist). Sollten wir früh scheitern und die ganze Seite brechen oder weiterarbeiten und darauf warten, dass jemand merkt, dass der Abschnitt "Benutzer" fehlt?
quelle
assert(foo != null, "foo is web control within the repeater, there's no reason to expect it to be null, etc, etc...");
Antworten:
Die Frage ist nicht so sehr, ob Sie nach
null
einer Ausnahme suchen oder diese zur Laufzeit auslösen sollen. So sollten Sie auf eine solche unerwartete Situation reagieren.Ihre Optionen sind dann:
NullReferenceException
) aus und lass sie explodieren. Wenn Sie dienull
Prüfung nicht selbst durchführen, geschieht dies automatisch.null
Schecks oder durch Abfangen einerNullReferenceException
und Auslösen der spezifischeren Ausnahme erreicht werden.Es gibt keine allgemeine Regel, welche die beste Lösung ist. Persönlich würde ich sagen:
quelle
IMHO, das versucht, Nullwerte zu behandeln, die Sie nicht erwarten, führt zu übermäßig kompliziertem Code. Wenn Sie keine Null erwarten, machen Sie dies durch Werfen deutlich
ArgumentNullException
. Ich bin sehr frustriert, wenn Leute prüfen, ob der Wert null ist, und dann versuchen, Code zu schreiben, der keinen Sinn ergibt. Das Gleiche gilt für die VerwendungSingleOrDefault
(oder noch schlimmer für das Abrufen von Sammlungen), wenn jemand wirklich erwartet,Single
und für viele andere Fälle, in denen die Leute Angst haben (ich weiß nicht genau, was), ihre Logik klar zu formulieren.quelle
ArgumentNullException
sollte man Codeverträge verwenden (es sei denn, es handelt sich um einen Quellcode vor 2010, der Codeverträge nicht unterstützt).ArgumentNullException
zählt das "Behandeln" des Nullwerts: Es verhindert eine spätere Nullreferenzausnahme.ArgumentNullException
macht es sehr klar, was das Problem ist und wie man es behebt. C # neigt nicht dazu, "undefiniert" zu verwenden. Wenn Sie etwas auf eine Art und Weise aufrufen, die nicht definiert ist, ist die Art und Weise, wie Sie es aufrufen, nicht sinnvoll. Eine Ausnahme ist der richtige Weg, dies anzuzeigen. Jetzt mache ich manchmal Parsing-Methoden, die null zurückgeben, wenn dasint
(zum Beispiel) nicht analysiert werden kann. Aber in diesem Fall ist ein nicht analysierbares Ergebnis eher eine legitime Möglichkeit als ein Verwendungsfehler. Siehe auch diesen Artikel .Die Angewohnheit,
null
nach meiner Erfahrung zu suchen, stammt von früheren C- oder C ++ - Entwicklern. In diesen Sprachen haben Sie gute Chancen, einen schwerwiegenden Fehler zu verbergen, wenn Sie nicht suchenNULL
. Wie Sie wissen, ist es in Java oder C # anders, wenn eine Nullreferenz ohne Prüfung aufnull
eine Ausnahme verwendet wird. Daher wird der Fehler nicht geheim ausgeblendet, solange Sie ihn auf der aufrufenden Seite nicht ignorieren. In den meisten Fällen macht das explizite Überprüfen aufnull
nicht viel Sinn und verkompliziert den Code mehr als nötig. Aus diesem Grund halte ich Nullprüfungen in diesen Sprachen nicht für eine gute Gewohnheit (zumindest nicht im Allgemeinen).Natürlich gibt es Ausnahmen von dieser Regel, hier sind die, an die ich denken kann:
Sie möchten eine besser lesbare Fehlermeldung erhalten, die dem Benutzer mitteilt, in welchem Teil des Programms die falsche Nullreferenz aufgetreten ist. Ihr Test für null löst also nur eine andere Ausnahme mit einem anderen Fehlertext aus. Offensichtlich wird kein Fehler auf diese Weise maskiert.
Sie möchten, dass Ihr Programm "früher scheitert". Sie möchten beispielsweise nach einem Nullwert eines Konstruktorparameters suchen, bei dem die Objektreferenz ansonsten nur in einer Mitgliedsvariablen gespeichert und später verwendet wird.
Sie können die Situation einer Nullreferenz sicher behandeln, ohne das Risiko nachfolgender Fehler und ohne Maskierung eines schwerwiegenden Fehlers.
Sie möchten eine ganz andere Art der Fehlersignalisierung (z. B. die Rückgabe eines Fehlercodes) in Ihrem aktuellen Kontext
quelle
Verwenden Sie Asserts , um Vor- / Nachbedingungen und Invarianten für Ihren Code zu testen und anzugeben.
Es macht es so viel einfacher zu verstehen, was der Code erwartet und was zu erwarten ist.
Eine Behauptung, IMO, ist eine geeignete Prüfung, da es sich um Folgendes handelt:
Ich halte es für wichtig, dass sich der Code selbst dokumentiert, daher ist eine Überprüfung gut. Defensive, ausfallsichere Programmierung erleichtert die Wartung, in der normalerweise die meiste Zeit aufgewendet wird.
Aktualisieren
Schreiben Sie Ihre Ausarbeitung. In der Regel ist es gut, dem Endbenutzer eine Anwendung zu geben, die auch bei Fehlern funktioniert, dh so viel wie möglich anzeigt. Robustheit ist gut, denn der Himmel weiß nur, was in einem kritischen Moment kaputt geht.
Entwickler und Tester müssen sich jedoch der Bugs so schnell wie möglich bewusst sein. Daher möchten Sie wahrscheinlich ein Protokollierungsframework mit einem Hook, das dem Benutzer eine Warnung anzeigt, dass ein Problem aufgetreten ist. Die Warnung sollte wahrscheinlich allen Benutzern angezeigt werden, kann jedoch je nach Laufzeitumgebung möglicherweise unterschiedlich angepasst werden.
quelle
Früh scheitern, oft scheitern.
null
ist einer der besten unerwarteten Werte, die Sie erhalten können, da Sie schnell versagen können, sobald Sie versuchen, ihn zu verwenden. Andere unerwartete Werte sind nicht so einfach zu erkennen. Danull
dies bei jedem Versuch automatisch fehlschlägt, würde ich sagen, dass keine explizite Überprüfung erforderlich ist.quelle
Das Überprüfen auf eine Null sollte Ihre zweite Natur sein
Ihre API wird von anderen Personen verwendet, und ihre Erwartungen unterscheiden sich wahrscheinlich von Ihren
Gründliche Komponententests machen normalerweise die Notwendigkeit einer Nullreferenzprüfung deutlich
Das Überprüfen auf Nullen impliziert keine bedingten Anweisungen. Wenn Sie befürchten, dass die Nullprüfung den Code weniger lesbar macht, sollten Sie .NET-Codeverträge in Betracht ziehen.
Erwägen Sie die Installation von ReSharper (oder ähnlichem), um Ihren Code nach fehlenden Nullreferenzprüfungen zu durchsuchen
quelle
Ich würde die Frage aus semantischer Sicht betrachten, dh mich fragen, was ein Nullzeiger oder ein Nullreferenzargument darstellt.
Wenn eine Funktion oder Methode foo () ein Argument x vom Typ T hat, kann x entweder obligatorisch oder optional sein .
In C ++ können Sie ein obligatorisches Argument als übergeben
In beiden Fällen haben Sie nicht das Problem, einen Nullzeiger zu überprüfen. Also, in vielen Fällen brauchen Sie nicht einen Null - Zeiger - Check überhaupt für die obligatorischen Argumente.
Wenn Sie ein optionales Argument übergeben, können Sie einen Zeiger verwenden und mit dem NULL-Wert angeben, dass kein Wert angegeben wurde:
Eine Alternative ist die Verwendung eines intelligenten Zeigers wie
In diesem Fall möchten Sie wahrscheinlich den Zeiger im Code überprüfen, da es für die Methode foo () von Bedeutung ist, ob x einen Wert oder gar keinen Wert enthält.
Der dritte und letzte Fall ist, dass Sie einen Zeiger für ein obligatorisches Argument verwenden. In diesem Fall ist der Aufruf von foo (x) mit x == NULL ein Fehler und Sie müssen entscheiden, wie Sie damit umgehen möchten (wie bei einem Out-of-Bound-Index oder einer ungültigen Eingabe):
Abgesehen von einer besseren Möglichkeit, Fehler zu machen (dem Benutzer mehr Informationen zu geben), besteht ein Vorteil des zweiten Ansatzes darin, dass der Fehler mit größerer Wahrscheinlichkeit gefunden wird: Das Programm schlägt jedes Mal fehl, wenn die Methode mit den falschen Argumenten aufgerufen wird, wohingegen mit Ansatz 1 Der Fehler tritt nur auf, wenn eine Anweisung ausgeführt wird, die den Zeiger dereferenziert (z. B. wenn der rechte Zweig einer if-Anweisung eingegeben wird). Ansatz 2 bietet daher eine stärkere Form des "frühzeitigen Scheiterns".
In Java haben Sie weniger Auswahlmöglichkeiten, da alle Objekte mit Referenzen übergeben werden, die immer null sein können. Auch hier ist die Überprüfung der Null (wahrscheinlich) Teil der Implementierungslogik, wenn die Null einen NONE-Wert eines optionalen Arguments darstellt.
Wenn die Null eine ungültige Eingabe ist, liegt ein Fehler vor und ich würde ähnliche Überlegungen anstellen wie im Fall von C ++ - Zeigern. Da Sie in Java Nullzeiger-Ausnahmen abfangen können, entspricht der obige Ansatz 1 dem Ansatz 2, wenn die Methode foo () alle Eingabeargumente in allen Ausführungspfaden dereferenziert (was bei kleinen Methoden wahrscheinlich sehr häufig vorkommt).
Zusammenfassend
BEARBEITEN
Vielen Dank an Stilgar für weitere Details.
In Ihrem Fall scheint es, dass Sie als Ergebnis einer Methode null haben. Ich denke, Sie sollten zunächst die Semantik Ihrer Methoden klären (und korrigieren), bevor Sie eine Entscheidung treffen können.
Sie haben also die Methode m1 (), die die Methode m2 () aufruft, und m2 () gibt eine Referenz (in Java) oder einen Zeiger (in C ++) auf ein Objekt zurück.
Was ist die Semantik von m2 ()? Soll m2 () immer ein Ergebnis ungleich Null zurückgeben? In diesem Fall ist ein Null-Ergebnis ein interner Fehler (in m2 ()). Wenn Sie den Rückgabewert in m1 () überprüfen, können Sie eine robustere Fehlerbehandlung haben. Wenn Sie dies nicht tun, werden Sie wahrscheinlich früher oder später eine Ausnahme haben. Vielleicht nicht. Hoffe, dass die Ausnahme während des Testens und nicht nach der Bereitstellung ausgelöst wird. Frage : Wenn m2 () niemals null zurückgeben sollte, warum gibt es null zurück? Vielleicht sollte es stattdessen eine Ausnahme auslösen? m2 () ist wahrscheinlich fehlerhaft.
Die Alternative besteht darin, dass die Rückgabe von null Teil der Semantik der Methode m2 () ist, dh ein optionales Ergebnis hat, das in der Javadoc-Dokumentation der Methode dokumentiert werden sollte. In diesem Fall ist es in Ordnung, einen Nullwert zu haben. Die Methode m1 () sollte es wie jeden anderen Wert prüfen: Hier liegt kein Fehler vor, aber wahrscheinlich ist die Prüfung, ob das Ergebnis null ist, nur ein Teil der Programmlogik.
quelle
Mein allgemeiner Ansatz ist es, niemals auf Fehlerzustände zu testen, bei denen Sie nicht wissen, wie Sie damit umgehen sollen . Dann lautet die Frage, die in jedem einzelnen Fall beantwortet werden muss: Können Sie angesichts des unerwarteten
null
Werts etwas Vernünftiges tun ?Wenn Sie sicher fortfahren können, indem Sie einen anderen Wert (z. B. eine leere Sammlung oder einen Standardwert oder eine leere Instanz) ersetzen, sollten Sie dies unbedingt tun. @ Shahbaz 'Beispiel aus World of Warcraft, ein Bild durch ein anderes zu ersetzen, fällt in diese Kategorie. Das Bild selbst ist wahrscheinlich nur eine Dekoration und hat keine funktionale Auswirkung. (Bei einem Debugbuild würde ich eine schreiende Farbe verwenden, um die Aufmerksamkeit auf die Tatsache zu lenken, dass eine Substitution stattgefunden hat, dies hängt jedoch stark von der Art der Anwendung ab.) Protokollieren Sie Details zu dem Fehler, damit Sie wissen, dass er auftritt. Andernfalls wird ein Fehler ausgeblendet, über den Sie wahrscheinlich etwas wissen möchten. Es ist eine Sache, es vor dem Benutzer zu verbergen (wiederum unter der Annahme, dass die Verarbeitung sicher fortgesetzt werden kann); es vor dem Entwickler zu verstecken ist etwas ganz anderes.
Wenn Sie bei einem Nullwert nicht sicher fortfahren können, schlagen Sie mit einem vernünftigen Fehler fehl. Im Allgemeinen versage ich lieber so schnell wie möglich, wenn es offensichtlich ist, dass die Operation nicht erfolgreich ist, was die Überprüfung der Voraussetzungen impliziert. Es gibt Zeiten, in denen Sie nicht sofort ausfallen möchten, sondern den Ausfall so lange wie möglich verschieben möchten. Diese Überlegung taucht beispielsweise in kryptografiebezogenen Anwendungen auf, in denen Seitenkanalangriffe möglicherweise Informationen preisgeben, die Sie nicht kennen möchten. Lassen Sie den Fehler am Ende zu einer allgemeinen Fehlerbehandlungsroutine aufsteigen, die relevante Details protokolliert und dem Benutzer eine nette (wie nett sie auch sein mögen) Fehlermeldung anzeigt.
Es ist auch erwähnenswert, dass die richtige Reaktion zwischen Test- / QA- / Debug-Builds und Produktions- / Release-Builds sehr unterschiedlich sein kann. Bei Debug-Builds würde ich mich bemühen, mit sehr detaillierten Fehlermeldungen frühzeitig und hart zu scheitern, um zu verdeutlichen, dass es ein Problem gibt, und einem Post-Mortem zu ermöglichen, zu bestimmen, was getan werden muss, um es zu beheben. Produktions-Builds sollten, wenn sie mit sicher behebbaren Fehlern konfrontiert werden, wahrscheinlich die Wiederherstellung begünstigen.
quelle
Klar
NULL
ist das nicht zu erwarten , aber es gibt immer Bugs!Ich glaube, Sie sollten überprüfen,
NULL
ob Sie es nicht erwarten. Lassen Sie mich Ihnen Beispiele geben (obwohl sie nicht in Java sind).In World of Warcraft erschien aufgrund eines Fehlers das Bild eines der Entwickler für viele Objekte auf einem Würfel. Stellen Sie sich vor, wenn die Grafik-Engine keine Zeiger erwartet
NULL
hätte, hätte es einen Absturz gegeben, während dies für den Benutzer zu einer nicht so tödlichen (sogar lustigen) Erfahrung wurde. Zumindest hätten Sie nicht unerwartet Ihre Verbindung oder einen Ihrer Speicherpunkte verloren.Dies ist ein Beispiel, in dem die Überprüfung auf NULL einen Absturz verhinderte und der Fall unbemerkt behandelt wurde.
Stellen Sie sich ein Programm für Bankangestellte vor. Die Schnittstelle führt einige Überprüfungen durch und sendet Eingabedaten an einen zugrunde liegenden Teil, um die Geldüberweisungen durchzuführen. Wenn der Kernteil erwartet, dass er nicht empfangen wird
NULL
, kann ein Fehler in der Schnittstelle ein Problem bei der Transaktion verursachen, möglicherweise geht etwas Geld in der Mitte verloren (oder schlimmer noch, es wird dupliziert).Mit "einem Problem" meine ich einen Absturz (wie bei einem Absturz (sagen wir, das Programm ist in C ++ geschrieben), keine Nullzeiger-Ausnahme). In diesem Fall muss die Transaktion zurückgesetzt werden, wenn NULL festgestellt wird (was natürlich nicht möglich wäre, wenn Sie die Variablen nicht mit NULL abgleichen würden!).
Ich bin mir sicher, dass Sie auf die Idee kommen.
Wenn Sie die Gültigkeit von Argumenten für Ihre Funktionen überprüfen, wird Ihr Code nicht überladen, da dies ein paar Überprüfungen am oberen Rand Ihrer Funktion darstellt (nicht in der Mitte verteilt) und die Robustheit erheblich erhöht.
Wenn Sie wählen müssen zwischen "Das Programm teilt dem Benutzer mit, dass ein Fehler aufgetreten ist, und wird ordnungsgemäß heruntergefahren oder in einen konsistenten Zustand zurückgesetzt, wodurch möglicherweise ein Fehlerprotokoll erstellt wird" und "Zugriffsverletzung", wählen Sie nicht das erste aus? Das bedeutet, dass jede Funktion darauf vorbereitet sein sollte, von einem Buggy-Code aufgerufen zu werden, anstatt zu erwarten, dass alles korrekt ist, einfach weil es immer Bugs gibt.
quelle
Wie die anderen Antworten zeigten Wenn Sie nicht erwarten
NULL
, machen Sie es klar, indem Sie werfenArgumentNullException
. Meiner Ansicht nach hilft es Ihnen beim Debuggen des Projekts , die Fehler in der Logik Ihres Programms früher zu erkennen.Sie werden also Ihre Software freigeben. Wenn Sie diese
NullRefrences
Überprüfungen wiederherstellen , verpassen Sie nichts an der Logik Ihrer Software. Sie stellen nur doppelt sicher, dass kein schwerwiegender Fehler auftritt.Ein weiterer Punkt ist, dass Sie bei der
NULL
Überprüfung der Parameter einer Funktion entscheiden können, ob die Funktion der richtige Ort ist oder nicht. Wenn nicht, suchen Sie alle Verweise auf die Funktion und übergeben Sie dann einen Parameter an die Funktion. Überprüfen Sie mögliche Szenarien, die zu einem Null-Verweis führen können.quelle
Jeder
null
in Ihrem System ist eine tickende Zeitbombe, die darauf wartet, entdeckt zu werden. Suchen Sienull
an den Grenzen, an denen Ihr Code mit Code interagiert, den Sie nicht kontrollieren, und verbieten Sienull
innerhalb Ihres eigenen Codes. Dies befreit Sie von dem Problem, ohne naiv Fremdcode zu vertrauen. Verwenden Sie stattdessen Ausnahmen oder eine ArtMaybe
/Nothing
Typ.quelle
Während eine Nullzeigerausnahme schließlich ausgelöst wird, wird sie häufig weit von dem Punkt entfernt ausgelöst, an dem Sie den Nullzeiger erhalten haben. Tun Sie sich selbst einen Gefallen und verkürzen Sie die Zeit, die zur Behebung des Fehlers benötigt wird, indem Sie zumindest protokollieren, dass Sie so schnell wie möglich einen Nullzeiger setzen.
Selbst wenn Sie nicht wissen, was Sie jetzt tun sollen, können Sie durch Protokollieren des Ereignisses später Zeit sparen. Und vielleicht kann derjenige, der das Ticket erhält, die eingesparte Zeit nutzen, um die richtige Antwort zu finden.
quelle
Da
Fail early, fail fast
wie von @DeadMG (@empi) angegeben nicht möglich ist, weil die Webanwendung bei Fehlern gut funktionieren muss, sollten Sie die Regel durchsetzenkeine ausnahme fangen ohne protokollierung
Sie als Entwickler sind sich potenzieller Probleme bewusst, indem Sie die Protokolle überprüfen.
Wenn Sie ein Protokollierungsframework wie log4net oder log4j verwenden, können Sie eine zusätzliche spezielle Protokollierungsausgabe (auch
als Appenderbezeichnet)einrichten, die Ihnen Fehler und schwerwiegende Fehler sendet.So bleiben Sie auf dem Laufenden.[aktualisieren]
Sollte dem Endbenutzer der Seite der Fehler nicht bekannt sein, können Sie einen Appender einrichten, der Sie per E-Mail über Fehler und schwerwiegende Fehler informiert.
Wenn es in Ordnung ist, dass dem Endbenutzer der Seite kryptische Fehlermeldungen angezeigt werden, können Sie einen Appender einrichten, der das Fehlerprotokoll für die Seitenverarbeitung am Ende der Seite platziert.
Unabhängig davon, wie Sie die Protokollierung verwenden, wenn Sie die Ausnahme verschlucken, fährt das Programm mit Daten fort, die sinnvoll sind, und das Verschlucken ist nicht mehr still.
quelle
Es gibt bereits gute Antworten auf diese Frage, vielleicht eine Ergänzung: Ich bevorzuge Behauptungen in meinem Code. Wenn Ihr Code nur mit gültigen Objekten, aber nicht mit Null arbeiten kann, sollten Sie den Wert Null angeben.
Aussagen in dieser Art von Situation würden dazu führen, dass alle Einheiten- und / oder Integrationstests mit der genauen Meldung fehlschlagen, sodass Sie das Problem vor der Produktion ziemlich schnell beheben können. Wenn ein solcher Fehler die Tests durchläuft und in die Produktion geht (wo Behauptungen deaktiviert werden sollten), erhalten Sie NpEx und einen schweren Fehler, aber es ist besser als ein kleinerer Fehler, der viel unscharfer ist und irgendwo anders in der Datenbank auftaucht Code, und wäre teurer zu beheben.
Wenn jemand mit Ihren Code-Behauptungen arbeiten muss, teilt er ihm außerdem Ihre Annahmen mit, die Sie beim Entwerfen / Schreiben Ihres Codes getroffen haben (in diesem Fall: Hey Mann, dieses Objekt muss präsentiert werden!), Was die Wartung erleichtert.
quelle
Normalerweise prüfe ich auf Nullen, aber ich "behandle" unerwartete Nullen, indem ich eine Ausnahme auslöse, die etwas detaillierter angibt, wo genau die Null aufgetreten ist.
Bearbeiten: Wenn Sie eine Null erhalten, wenn Sie nicht erwarten, dass etwas nicht stimmt, sollte das Programm sterben.
quelle
Dies hängt von der Sprachimplementierung der Ausnahmen ab. Mit Ausnahmen können Sie Maßnahmen ergreifen, um Datenschäden zu vermeiden oder Ressourcen sauber freizugeben, falls Ihr System in einen unerwarteten Zustand übergeht. Dies unterscheidet sich von der Fehlerbehandlung, bei der es sich um einen zu erwartenden Zustand handelt. Meine Philosophie ist, dass Sie so wenig Ausnahmebehandlung wie möglich haben sollten. Es ist Lärm. Kann Ihre Methode durch die Behandlung der Ausnahme etwas Vernünftiges bewirken? Kann es sich erholen? Kann es weitere Schäden reparieren oder verhindern? Wenn Sie nur die Ausnahme abfangen und dann von der Methode zurückkehren oder auf eine andere harmlose Weise versagen, war es wirklich sinnlos, die Ausnahme abzufangen. Sie hätten Ihrer Methode nur Rauschen und Komplexität hinzugefügt, und Sie könnten die Ursache eines Fehlers in Ihrem Entwurf verbergen. In diesem Fall würde ich den Fehler in die Luft sprudeln lassen und von einer äußeren Schleife erfasst werden. Wenn Sie beispielsweise ein Objekt reparieren oder als beschädigt markieren oder eine kritische Ressource wie eine Sperrdatei freigeben oder einen Socket sauber schließen können, sind Ausnahmen sinnvoll. Wenn Sie tatsächlich erwarten, dass der NULL-Wert häufig als gültiger Flankenfall angezeigt wird, sollten Sie dies im normalen logischen Ablauf mit if-the-else- oder switch-case-Anweisungen oder was auch immer behandeln, nicht mit einer Ausnahmebehandlung. Beispielsweise kann ein in einem Formular deaktiviertes Feld auf NULL gesetzt werden, was sich von einer leeren Zeichenfolge unterscheidet, die ein Feld darstellt, das leer gelassen wird. Dies ist ein Bereich, in dem Sie ein gutes Urteilsvermögen und gesunden Menschenverstand anwenden müssen. Ich habe noch nie von soliden Faustregeln gehört, wie man mit diesem Problem in jeder Situation umgeht. Wenn Sie beispielsweise ein Objekt reparieren oder als beschädigt markieren oder eine kritische Ressource wie eine Sperrdatei freigeben oder einen Socket sauber schließen können, sind Ausnahmen sinnvoll. Wenn Sie tatsächlich erwarten, dass der NULL-Wert häufig als gültiger Flankenfall angezeigt wird, sollten Sie dies im normalen logischen Ablauf mit if-the-else- oder switch-case-Anweisungen oder was auch immer behandeln, nicht mit einer Ausnahmebehandlung. Beispielsweise kann ein in einem Formular deaktiviertes Feld auf NULL gesetzt werden, was sich von einer leeren Zeichenfolge unterscheidet, die ein Feld darstellt, das leer gelassen wird. Dies ist ein Bereich, in dem Sie ein gutes Urteilsvermögen und gesunden Menschenverstand anwenden müssen. Ich habe noch nie von soliden Faustregeln gehört, wie man mit diesem Problem in jeder Situation umgeht. Wenn Sie beispielsweise ein Objekt reparieren oder als beschädigt markieren oder eine kritische Ressource wie eine Sperrdatei freigeben oder einen Socket sauber schließen können, sind Ausnahmen sinnvoll. Wenn Sie tatsächlich erwarten, dass NULL häufig als gültiger Randfall angezeigt wird, sollten Sie dies im normalen logischen Ablauf mit if-the-else- oder switch-case-Anweisungen oder was auch immer behandeln, nicht mit einer Ausnahmebehandlung. Beispielsweise kann ein in einem Formular deaktiviertes Feld auf NULL gesetzt werden, was sich von einer leeren Zeichenfolge unterscheidet, die ein Feld darstellt, das leer gelassen wird. Dies ist ein Bereich, in dem Sie ein gutes Urteilsvermögen und gesunden Menschenverstand anwenden müssen. Ich habe noch nie von soliden Faustregeln gehört, wie man mit diesem Problem in jeder Situation umgeht.
Java schlägt bei der Implementierung der Ausnahmebehandlung mit "überprüften Ausnahmen" fehl, bei der jede mögliche Ausnahme, die von in einer Methode verwendeten Objekten ausgelöst werden kann, in der "throws" -Klausel der Methode abgefangen oder deklariert werden muss. Das ist das Gegenteil von C ++ und Python, wo Sie Ausnahmen behandeln können, wie Sie es für richtig halten. Wenn Sie in Java den Hauptteil einer Methode so ändern, dass er einen Aufruf enthält, der möglicherweise eine Ausnahme auslöst, stehen Sie vor der Wahl, eine explizite Behandlung für eine Ausnahme hinzuzufügen, die Sie möglicherweise nicht interessieren und die Ihrem Code Rauschen und Komplexität hinzufügt, oder Sie müssen Fügen Sie diese Ausnahme zur "throws" -Klausel der zu ändernden Methode hinzu, die nicht nur Rauschen und Unordnung verursacht, sondern auch die Signatur Ihrer Methode ändert. Sie müssen dann einen Änderungscode eingeben, wo immer Ihre Methode verwendet wird, um entweder die neue Ausnahme zu behandeln, die Ihre Methode jetzt auslöst, oder die Ausnahme der "throws" -Klausel dieser Methoden hinzufügen, wodurch ein Dominoeffekt von Codeänderungen ausgelöst wird. Die "Catch or Specify Requirement" muss einer der nervigsten Aspekte von Java sein. Die Ausnahme Ausnahme für RuntimeExceptions und die offizielle Java-Rationalisierung für diesen Entwurfsfehler ist lahm.
Dieser letzte Absatz hatte wenig mit der Beantwortung Ihrer Frage zu tun. Ich hasse Java einfach.
- Noah
quelle