it-swarm.com.de

Wann eine Assertion und wann eine Ausnahme verwendet wird

Meistens werde ich eine Ausnahme verwenden, um nach einer Bedingung in meinem Code zu suchen. Ich frage mich, wann es an der Zeit ist, eine Assertion zu verwenden.

Zum Beispiel,

Group group=null;
try{
    group = service().getGroup("abc");
}catch(Exception e){
    //I dont log error because I know whenever error occur mean group not found
}

if(group !=null)
{
    //do something
}

Könnten Sie angeben, wie eine Behauptung hier passt? Soll ich eine Behauptung verwenden?

Es scheint, als würde ich niemals Assertions im Produktionscode verwenden und sehe nur Assertions in Unit-Tests. Ich weiß, dass ich in den meisten Fällen nur die Ausnahme verwenden kann, um die Überprüfung wie oben auszuführen, aber ich möchte wissen, wie es "professionell" ist.

106
cometta

Assertionen sollten verwendet werden, um etwas zu überprüfen, das niemals passieren sollte, während eine Ausnahme verwendet werden sollte, um zu überprüfen, ob etwas passiert. 

Beispielsweise könnte eine Funktion durch 0 dividiert werden, daher sollte eine Ausnahme verwendet werden. Mit einer Assertion kann jedoch überprüft werden, ob die Festplatte plötzlich verschwindet. 

Eine Zusicherung würde die Ausführung des Programms stoppen, eine Ausnahme würde jedoch die Ausführung des Programms fortsetzen.

Beachten Sie, dass if(group != null) keine Zusicherung ist, sondern lediglich eine Bedingung.

78
Marius

Meiner Meinung nach (die Liste ist möglicherweise unvollständig und zu lang für einen Kommentar), würde ich sagen:

  • verwenden Sie Ausnahmen, wenn Sie Parameter überprüfen, die an öffentliche oder geschützte Methoden und Konstruktoren übergeben werden
  • verwenden Sie Ausnahmen, wenn Sie mit dem Benutzer interagieren oder wenn Sie erwarten, dass sich der Clientcode nach einer Ausnahmesituation erholt
  • verwenden Sie Ausnahmen, um mögliche Probleme zu beheben
  • verwenden Sie Zusicherungen, um Vorbedingungen, Nachbedingungen und Invarianten von privatem/internem Code zu überprüfen
  • verwenden Sie Zusicherungen, um sich oder Ihrem Entwicklerteam Feedback zu geben
  • verwenden Sie Assertions, wenn Sie nach Dingen suchen, die sehr unwahrscheinlich sind. Andernfalls bedeutet dies, dass Ihre Anwendung einen schwerwiegenden Fehler aufweist
  • verwenden Sie Behauptungen, um Dinge zu sagen, von denen Sie (angeblich) wissen, dass sie wahr sind

Mit anderen Worten, Ausnahmen beziehen sich auf die Robustheit Ihrer Anwendung, während Behauptungen ihre Korrektheit betreffen.

Assertions sind so konzipiert, dass sie billig zu schreiben sind. Sie können sie fast überall verwenden. Ich verwende diese Faustregel: Je mehr eine Assertionsaussage dumm erscheint, desto wertvoller ist sie und desto mehr Informationen werden eingebettet. Wenn Sie ein Programm debuggen, das sich nicht richtig verhält, werden Sie die offensichtlichen Fehlermöglichkeiten anhand Ihrer Erfahrung sicher prüfen. Dann werden Sie nach Problemen suchen, die einfach nicht passieren können: Genau hier helfen Behauptungen viel und sparen Zeit.

159
Gregory Pakosz

Denken Sie daran, dass Assertions zur Laufzeit mithilfe von Parametern deaktiviert werden können, und sind standardmäßig deaktiviert . Sie sollten daher nicht mit Ausnahme von Debugging-Zwecken rechnen.

Sie sollten auch den Oracle-Artikel über assert lesen, um mehr Fälle zu sehen, in denen assert verwendet wird oder nicht.

25
chburd

Generell:

  • Verwenden Sie Assertions für interne Konsistenzprüfungen, bei denen es egal ist, ob jemand sie abschaltet. (Beachten Sie, dass der Befehl Java standardmäßig alle Assertions deaktiviert.)
  • Verwenden Sie regelmäßige Tests für jegliche Art von Prüfungen, die nicht deaktiviert werden sollten. Diese enthält defensive Überprüfungen, die einen potenziellen Schaden durch Fehler, Validierungsdaten/-anforderungen/was auch immer von Benutzern oder externen Diensten bereitgestellt werden, schützen.

Der folgende Code aus Ihrer Frage ist fehlerhaft und möglicherweise fehlerhaft

try {
    group = service().getGroup("abc");
} catch (Exception e) {
    //i dont log error because i know whenever error occur mean group not found
}

Das Problem ist, dass Sie NICHT wissen, dass eine Ausnahme bedeutet, dass die Gruppe nicht gefunden wurde. Es ist auch möglich, dass der Aufruf von service() eine Ausnahmebedingung ausgelöst hat oder dass null zurückgegeben wurde, die dann eine NullPointerException verursachte.

Wenn Sie eine "erwartete" Ausnahme abfangen, sollten Sie nur die Ausnahme abfangen, die Sie erwarten. Indem Sie Java.lang.Exception abfangen (und vor allem, indem Sie es nicht protokollieren), wird es schwieriger, das Problem zu diagnostizieren/zu debuggen, und die App kann möglicherweise mehr Schaden anrichten.

15
Stephen C

Nun, bei Microsoft war es die Empfehlung, Ausnahmen in alle APIs zu werfen, die Sie öffentlich zur Verfügung stellen, und Asserts in allen möglichen Annahmen zu verwenden, die Sie bezüglich internem Code treffen. Es ist ein bisschen lose Definition, aber ich denke, es liegt an jedem Entwickler, die Grenze zu ziehen.

In Bezug auf die Verwendung von Exceptions sollte, wie der Name schon sagt, ihre Verwendung außergewöhnlich sein. Für den oben angegebenen Code sollte der Aufruf getGroupnull zurückgeben, wenn kein Dienst vorhanden ist. Eine Ausnahme sollte nur dann auftreten, wenn eine Netzwerkverbindung ausfällt oder ähnliches.

Ich denke, die Schlussfolgerung ist, dass das Entwicklungsteam für jede Anwendung ein wenig übrig bleibt, um die Grenzen von Assert vs. Exceptions zu definieren.

3
rui

Laut diesem Dokument http://docs.Oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , "Die Assert-Aussage ist für die nichtöffentliche Vorbedingung geeignet. Nachbedingungen und Klasseninvariantenprüfung. Die Überprüfung der öffentlichen Voraussetzungen sollte weiterhin durch Prüfungen innerhalb von Methoden durchgeführt werden, die insbesondere zu dokumentierten Ausnahmen führen, z. B. IllegalArgumentException und IllegalStateException. "

Wenn Sie mehr über Vorbedingungen, Nachbedingungen und Klasseninvarianten erfahren möchten, lesen Sie dieses Dokument: http://docs.Oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions . Es enthält auch Beispiele für die Verwendung von Assertions.

3
cesarsalgado

Beim Testen auf null werden nur Nullwerte abgefangen, die Probleme verursachen, während ein Try/Catch-Vorgang, wie Sie ihn haben, any error abfängt.

Im Großen und Ganzen ist Try/Catch sicherer, aber etwas langsamer, und Sie müssen darauf achten, dass Sie alle möglichen Fehler auffangen. Ich würde also try/catch sagen - eines Tages kann sich der getGroup-Code ändern, und Sie brauchen vielleicht nur das größere Netz.

1
Phil H

Sie können diesen einfachen Unterschied im Hinblick auf ihre Verwendung verwenden. Ausnahmen werden verwendet, um erwartete und unerwartete Fehler zu überprüfen, die als geprüfter und ungeprüfter Fehler bezeichnet werden, während Assertion hauptsächlich zu Debugging-Zwecken zur Laufzeit verwendet wird, um festzustellen, ob die Annahmen validiert sind oder nicht. 

1
SBTec

Siehe Abschnitt 6.1.2 (Zusicherungen vs. anderer Fehlercode) der Sun-Dokumentation unter dem folgenden Link. 

http://www.Oracle.com/technetwork/articles/javase/javapch06.pdf

Dieses Dokument gibt den besten Rat, den ich je gesehen habe, wann Assertions verwendet werden sollten. Zitieren aus dem Dokument:

"Eine gute Faustregel ist, dass Sie eine Behauptung für Ausnahmefälle verwenden sollten, die Sie vergessen möchten. Eine Behauptung ist der schnellste Weg, um mit einer Bedingung umzugehen, die Sie nicht zu erwarten haben, und zu vergessen Zurecht kommen."

1
Phil

Ich gestehe, ich bin etwas verwirrt von Ihrer Frage. Wenn eine Assertionsbedingung nicht erfüllt ist, wird eine Ausnahme ausgelöst. Verwirrend wird dies als AssertionError bezeichnet. Beachten Sie, dass es nicht markiert ist, wie (zum Beispiel) IllegalArgumentException , das unter sehr ähnlichen Umständen ausgelöst wird.

Also mit Assertions in Java

  1. ist ein prägnanteres Mittel zum Schreiben eines Condition/Throw-Blocks
  2. erlaubt Ihnen, diese Prüfungen über JVM-Parameter ein- und auszuschalten. Normalerweise würde ich diese Überprüfungen immer beibehalten, es sei denn, sie beeinträchtigen die Laufzeitleistung oder haben eine ähnliche Strafe.
1
Brian Agnew

Leider können Zusicherungen deaktiviert werden. Wenn Sie in der Produktion alle Hilfe benötigen, die Sie erhalten können, wenn Sie etwas Unvorhergesehenes aufspüren, können Sie sich disqualifizieren.