2015-02-12 9 views
6

Ich bin die Quelle XWalkUIClientInternal lesen, und ich lief in den folgenden Code ein:assert (false) vs RuntimeException?

switch(type) { 
     case JAVASCRIPT_ALERT: 
      return onJsAlert(view, url, message, result); 
     case JAVASCRIPT_CONFIRM: 
      return onJsConfirm(view, url, message, result); 
     case JAVASCRIPT_PROMPT: 
      return onJsPrompt(view, url, message, defaultValue, result); 
     case JAVASCRIPT_BEFOREUNLOAD: 
      // Reuse onJsConfirm to show the dialog. 
      return onJsConfirm(view, url, message, result); 
     default: 
      break; 
    } 
    assert(false); 
    return false; 

Ich habe nie wirklich diese Technik noch wirklich darüber gesehen dachte, aber ich denke, das bedeutet im Wesentlichen: „Das ist nicht erreichbar Code und sollte nie passieren ", und crash die App, egal was. Technisch kann man das mit einem Throwable, solange es nicht erwischt wird.

Also meine Frage ist, welche ist besser und warum, assert(false) oder werfen RuntimeException, oder vielleicht eine Error?

Antwort

9

Der größte Unterschied zwischen

assert false; 

(Die Klammern sind nicht erforderlich, assert ist keine Funktion, sondern eine Feststellung.) Und

throw new RuntimeException(); 

ist, dass die Behauptung deaktiviert werden kann. Tatsächlich ist standardmäßig deaktiviert, es sei denn, die JVM wird mit dem Flag -ea ("aktiviert Assertionen") gestartet. Wenn Assertions aktiviert sind, wird assert false bedingungslos eine AssertionError auslösen, die von Error abgeleitet ist. Aber da Behauptungen deaktiviert werden können, gibt es zwei Probleme,

  • der Fehler unentdeckt bleiben könnte und
  • Steuerflussanalyse erfordert eine Dummy-return Anweisung nach der assert (die meist Unordnung ist).

daher im obigen Fall, würde ich auf jeden Fall mit einer expliziten gehen (und prägnanten)

throw new AssertionError("invalid type " + type); 

anstelle einem durch eine Dummy-return gefolgt assert.

Wie in den Kommentaren erwähnt, wird angenommen, dass type ein interner Parameter ist und ein ungültiger Wert einen Fehler in der Logik selbst anzeigt. Wenn es sich um einen Eingabeparameter handelt, sollte dieser gemäß den üblichen Regeln validiert werden und IllegalArgumentException wird ausgelöst, wenn die Validierung fehlschlägt.

+0

Und wenn Sie etwas werfen wollten, würden Sie eine 'RuntimeException' werfen, so dass nicht einmal' catch (Exception e) 'es fangen würde, oder eine Unterklasse von' Error'? – EpicPandaForce

+1

Sie können einen 'AssertionError' werfen, das ist wahrscheinlich am besten geeignet. Ich habe meine Antwort entsprechend bearbeitet. – 5gon12eder

+0

Ja, Sie haben Recht, das scheint der beste Ansatz zu sein. Es ist informativer als nur 'Assertion failed: false' und wird nicht von einem' 'catch (Exception e)' Zweig abgefangen. – EpicPandaForce

1

Nach den Oracle guidelines (Programming with assertions) wurden Behauptungen zu Testzwecken entwickelt:

Eine Behauptung eine Erklärung in der Programmiersprache Java ist, dass Sie Ihre Annahmen über Ihr Programm testen kann. Beispiel: Wenn Sie eine Methode schreiben, mit der die Geschwindigkeit eines Partikels berechnet wird, geben Sie unter an, dass die berechnete Geschwindigkeit kleiner als die Geschwindigkeit light ist.

Jede Assertion enthält einen booleschen Ausdruck, von dem Sie glauben, dass er true ist, wenn die Assertion ausgeführt wird. Wenn es nicht wahr ist, wird das System einen Fehler werfen. Durch die Bestätigung, dass der boolesche Ausdruck tatsächlich wahr ist, bestätigt die Assertion Ihre Annahmen über das Verhalten von Ihrem Programm und erhöht Ihr Vertrauen, dass das Programm frei von Fehlern ist.

In Ihrem Beispiel ging der Entwickler davon aus, dass der Code niemals die assert-Anweisung erreicht. Wenn es selten passiert, wird die assert(false) eine Error werfen (da es nie dorthin gelangen sollte). Dies wurde zu Testzwecken getan. Verwenden Sie Assert also ausschließlich zu Testzwecken.

+0

Wenn es zu Testzwecken ist, warum funktioniert ein Unit-Test \t @Test \t public void Test() \t { \t \t Methode(); \t} \t private void-Methode() \t { \t \t behaupten falsch: "me Crash"; \t} übergeben? –

+0

@ ᵺṓᵯᶏᵴ, beziehen Sie sich auf JUnit 'assertFalse()' oder Java-spezifische 'assert'? JUnits "AssertFalse" bestätigt, dass die "Bedingung" "falsch" ist, so dass ein "false" übergeben wird. Ich beziehe mich nicht auf 'AssertFalse' von JUnit oder TestNG, sondern auf Javas eigenes' assert'. –

+0

Ich habe 'assertFalse() 'nicht in meinem Code verwendet. Ich habe 'Assert false' nur verwendet. –

Verwandte Themen