Ich werfe nie NullPointerException . Für mich ist es eine, die ganz natürlich im Code auftaucht, wenn etwas schief geht, und die einen Entwickler dazu zwingt, sich anzusehen, was passiert. Dann behebt er die Ursache und das Problem tritt nicht mehr auf.
Ich benutze IllegalStateException um zu signalisieren, dass ein Objekt falsch konfiguriert ist oder dass die Reihenfolge der Aufrufe nicht stimmt. Wir alle wissen jedoch, dass ein Objekt idealerweise sicherstellen sollte, dass es sich nicht in einem schlechten Zustand befinden kann und dass man es nicht in falscher Reihenfolge aufrufen kann (einen Builder und ein daraus resultierendes Objekt erstellen ...).
Ich verwende eine Menge IllegalArgumentException wenn eine Methode feststellt, dass ihre Parameter falsch sind. Dies ist die Aufgabe jeder öffentlichen Methode, die Verarbeitung abzubrechen (um indirekte Fehler zu vermeiden, die schwieriger zu verstehen sind). Außerdem gibt es einige if
s am Anfang einer Methode dienen der Dokumentation (Dokumentation, die nie vom Code abweicht, weil es der Code ist :-) ).
public void myMethod(String message, Long id) {
if (message == null) {
throw new IllegalArgumentException("myMethod's message can't be null");
// The message doesn't log the argument because we know its value, it is null.
}
if (id == null) {
throw new IllegalArgumentException("myMethod's id can't be null");
// This case is separated from the previous one for two reasons :
// 1. to output a precise message
// 2. to document clearly in the code the requirements
}
if (message.length()<12) {
throw new IllegalArgumentException("myMethod's message is too small, was '" + message + "'");
// here, we need to output the message itself,
// because it is a useful debug information.
}
}
Ich verwende auch spezifische Laufzeitausnahmen um außergewöhnliche Bedingungen auf höherer Ebene zu signalisieren.
Wenn zum Beispiel ein Modul meiner Anwendung nicht gestartet werden kann, könnte ich eine ModuleNotOperationalException (idealerweise durch einen generischen Code wie einen Interceptor, andernfalls durch einen spezifischen Code), wenn ein anderes Modul es aufruft. Nach dieser architektonischen Entscheidung muss jedes Modul mit dieser Ausnahme bei Operationen umgehen, die andere Module aufrufen...