Ich habe diese Frage gesehen, habe aber noch einige Fragen zur Verwendung des assert
Schlüsselworts. Ich habe mit ein paar anderen Programmierern über die Verwendung diskutiert assert
. Für diesen Anwendungsfall gab es eine Methode, die null zurückgeben kann, wenn bestimmte Voraussetzungen erfüllt sind. Der von mir geschriebene Code ruft die Methode auf, gibt dann an, dass sie nicht null zurückgibt, und verwendet weiterhin das zurückgegebene Objekt.
Beispiel:
class CustomObject {
private Object object;
@Nullable
public Object getObject() {
return (object == null) ? generateObject() : object;
}
}
Stellen Sie sich jetzt vor, ich benutze es so:
public void useObject(CustomObject customObject) {
object = customObject.getObject();
assert object != null;
// Do stuff using object, which would throw a NPE if object is null.
}
Mir wurde gesagt, ich sollte das entfernen assert
, dass sie niemals im Produktionscode verwendet werden sollten, sondern nur zum Testen. Ist das wahr?
-ea
oder gleichwertig aktivieren .Objects.requireNonNull
in Java 8 nicht mehr erforderlich ist ).Antworten:
Verwenden Sie
Objects.requireNonNull(Object)
dafür.In Ihrem Fall wäre dies:
Diese Funktion wurde für die von Ihnen genannten Zwecke ausgeführt, dh markieren Sie explizit, was nicht null sein soll. auch in der Produktion. Der große Vorteil ist, dass Sie sicherstellen, dass Sie Nullwerte genau dort finden, wo sie überhaupt nicht auftreten sollten. Sie haben weniger Probleme beim Debuggen von Problemen, die durch Nullwerte verursacht werden, die an einer Stelle übergeben wurden, an der sie nicht sein sollten.
Ein weiterer Vorteil ist die zusätzliche Flexibilität bei Nullprüfungen im Gegensatz zu
assert
. Währendassert
es sich um ein Schlüsselwort zum Überprüfen eines booleschen Werts handelt,Objects.requireNonNull(Object)
handelt es sich um eine Funktion, die viel flexibler und lesbarer in Code eingebettet werden kann. Z.B:Beachten Sie, dass dies
Objects.requireNonNull(Object)
ausschließlich zur Nullprüfung dient, wenn diesassert
verallgemeinert ist.assert
hat in dieser Hinsicht leicht unterschiedliche Zwecke, dh hauptsächlich das Testen. Es muss aktiviert sein, damit Sie es zum Testen aktivieren und für die Produktion deaktivieren können. Verwenden Sie es sowieso nicht für Produktionscode. Dies könnte die Anwendung durch unnötige und komplizierte Validierungen verlangsamen, die zum Testen vorgesehen sind. Verwenden Sie diese Option, um Nur-Test-Prüfungen von Prüfungen zu trennen, die auch für die Produktion bestimmt sind.Weitere Informationen finden Sie in der offiziellen Dokumentation
assert
.quelle
Das Wichtigste, an das Sie sich bei Behauptungen erinnern sollten, ist, dass sie deaktiviert werden können. Gehen Sie also niemals davon aus, dass sie ausgeführt werden.
Aus Gründen der Abwärtskompatibilität deaktiviert die JVM die Validierung von Zusicherungen standardmäßig. Sie müssen explizit aktiviert werden, indem entweder das Befehlszeilenargument -enableassertions oder die Kurzform -ea verwendet wird:
Es ist also keine gute Praxis, sich auf sie zu verlassen.
Da Zusicherungen nicht standardmäßig aktiviert sind, können Sie niemals davon ausgehen, dass sie bei Verwendung im Code ausgeführt werden. Sie sollten daher immer nach Nullwerten und leeren Optionals suchen, die Verwendung von Zusicherungen zum Einchecken von Eingaben in eine öffentliche Methode vermeiden und stattdessen eine ungeprüfte Ausnahme verwenden ... Führen Sie im Allgemeinen alle Überprüfungen so durch, als ob die Zusicherung nicht vorhanden wäre.
quelle
Sicherlich ist das, was Ihnen gesagt wird, eine offensichtliche Lüge. Hier ist der Grund.
Zusicherungen sind standardmäßig deaktiviert, wenn Sie nur eigenständiges JVM ausführen. Wenn sie deaktiviert sind, haben sie keinen Platzbedarf, daher haben sie keine Auswirkungen auf Ihre Produktionsanwendung. Sie sind jedoch wahrscheinlich Ihre besten Freunde beim Entwickeln und Testen Ihres Codes, und die meisten Test-Framework-Läufer aktivieren Assertions (JUnit), sodass Ihr Assertion-Code ausgeführt wird, wenn Sie Ihre Unit-Tests ausführen, um potenzielle Fehler früher zu erkennen (z Sie können Asserts für einige Business Logic Boundary Checks hinzufügen. Dies hilft dabei, Code zu erkennen, der unangemessene Werte verwendet.
Wie aus der anderen Antwort hervorgeht, können Sie sich aus genau diesem Grund (sie sind nicht immer aktiviert) nicht auf Behauptungen verlassen, um wichtige Überprüfungen durchzuführen oder (insbesondere!) Einen Zustand beizubehalten.
Ein interessantes Beispiel für die Verwendung von Asserts finden Sie hier. Am Ende der Datei befindet sich eine Methode,
singleThreadedAccess()
die aus der assert-Anweisung in Zeile 201 aufgerufen wird und dazu dient, potenziellen Multithread-Zugriff in Tests abzufangen.quelle
Die anderen Antworten decken dies bereits gut genug ab, aber es gibt andere Möglichkeiten.
Zum Beispiel hat Spring eine statische Methode:
org.springframework.util.Assert.notNull(obj)
Es gibt auch andere Bibliotheken mit eigenen
Assert.something()
Methoden. Es ist auch ziemlich einfach, eigene zu schreiben.Beachten Sie jedoch, welche Ausnahmen Sie auslösen, wenn es sich um einen Webdienst handelt. Die zuvor erwähnte Methode löst beispielsweise eine aus,
IllegalArgumentException
die in Spring standardmäßig eine 500 zurückgibt.Im Fall eines Webdienstes handelt es sich häufig nicht um einen internen Serverfehler, und es sollte sich nicht um einen 500 handeln, sondern um einen 400, was eine schlechte Anforderung darstellt.
quelle
assert
ist, einen sofortigen Absturz mit einer erstellten Kerndatei zu erreichen, damit Sie mit Ihrem bevorzugten Debugger genau an der Stelle, an der die Bedingung verletzt wurde, ein Post-Mortem durchführen können.assert
zu werfen. Interessant. Die C / C ++ - Version macht so etwas nicht. Es wird sofort ein Signal ausgelöst, dass a) der Prozess abgebrochen wird und b) ein Core Dump erstellt wird. Dies geschieht aus einem Grund: Es ist kinderleicht, einen solchen Assertionsfehler zu debuggen, da Sie immer noch über die gesamten Informationen zum Aufrufstapel verfügen. Die Definitionassert
, stattdessen eine Ausnahme auszulösen, die dann (un) absichtlich programmatisch abgefangen werden kann, vereitelt den Zweck, imho.Throwable
. Sie können immer gefangen werden. Ob das gut ist oder nicht, weiß ich nicht. Ich denke es kommt darauf an. Viele Java-Programme sind Webdienste, und es wäre unerwünscht, wenn sie aus fast jedem Grund abstürzen würden, sodass fast alles abgefangen und protokolliert wird. Eines der großartigen Dinge ist die Stapelverfolgung, und dies reicht normalerweise aus, um den Grund für eine Ausnahme oder einen Fehler selbst zu diagnostizieren.Verwenden Sie Asserts großzügig, wenn dies dazu beiträgt, Programmierfehler, z. B. Fehler, zu erkennen.
Verwenden Sie assert nicht, um etwas abzufangen, das logisch passieren könnte, dh schlecht formatierte Eingaben. Verwenden Sie assert nur, wenn der Fehler nicht behoben werden kann.
Fügen Sie keine Produktionslogik in den Code ein, der ausgeführt wird, wenn die Zusicherung überprüft wird. Wenn Ihre Software gut geschrieben ist, ist dies trivial wahr, aber wenn dies nicht der Fall ist, können subtile Nebenwirkungen und ein unterschiedliches Gesamtverhalten auftreten, wenn Behauptungen aktiviert und deaktiviert sind.
Wenn in Ihrem Unternehmen "Testcode" und "Produktionscode" dasselbe tun, jedoch unterschiedliche Codebasen (oder unterschiedliche Bearbeitungsstufen), verlassen Sie diese und kommen Sie nie wieder zurück. Der Versuch, dieses Maß an Inkompetenz zu beheben, ist wahrscheinlich Zeitverschwendung. Wenn Ihr Unternehmen keine Assert-Anweisung außerhalb des Testcodes platziert, teilen Sie ihm bitte mit, dass Asserts im Produktionsbuild deaktiviert sind und dass die Behebung dieses Fehlers jetzt Ihre erste Priorität ist, wenn dies nicht der Fall ist.
Der Wert von Asserts ist genau innerhalb der Geschäftslogik und nicht nur innerhalb der Testsuite zu verwenden. Dies macht es einfach, viele Tests auf hoher Ebene durchzuführen, bei denen nicht viele Dinge explizit getestet werden müssen, um große Teile Ihres Codes zu durchlaufen und all diese Behauptungen auszulösen. In einigen meiner Projekte haben typische Tests nicht einmal wirklich etwas bestätigt, sondern nur eine Berechnung angeordnet, die auf bestimmten Eingaben basiert. Dies führte dazu, dass Hunderte von Aussagen überprüft wurden und Probleme selbst in winzigen logischen Teilen tief im Inneren gefunden wurden.
quelle
Sie können assert jederzeit verwenden. Die Debatte kommt, wann zu verwenden. Zum Beispiel in der Anleitung :
quelle