HOWTO · Java
RuntimeException in Java: Bedeutung, Beispiele und geprüfte Ausnahmen
Erfahren Sie, was java.lang.RuntimeException in Java bedeutet, sehen Sie häufige Ursachen und vergleichen Sie ungeprüfte Laufzeitausnahmen mit geprüften Ausnahmen.
Auf dieser Seite
java.lang.RuntimeException ist die Basisklasse für ungeprüfte Ausnahmen in Java. Der Compiler verlangt nicht, dass eine Methode eine solche Ausnahme abfängt oder mit throws deklariert. Ein Programm kann sie jedoch abfangen, wenn eine angemessene Wiederherstellung möglich ist. Laufzeitausnahmen weisen häufig auf einen Fehler in der Programmlogik oder auf eine nicht erfüllte Annahme hin.
java.lang.RuntimeException in Java verstehen
Eine Laufzeitausnahme kann auftreten, während ein Programm ausgeführt wird. Häufige Beispiele sind NullPointerException, ArrayIndexOutOfBoundsException und ArithmeticException. Ihre Namen beschreiben unterschiedliche Fehler:
- Eine
NullPointerExceptionkann auftreten, wenn der Code eine Nullreferenz dereferenziert, zum Beispiellength()für eine Zeichenkette aufruft, dienullist. - Eine
ArrayIndexOutOfBoundsExceptionkann auftreten, wenn der Code an einer Arrayposition liest oder schreibt, die kleiner als null oder mindestens so groß wie die Arraylänge ist. Bei einem Array der Länge fünf sind die Indizes null bis vier gültig. - Eine
ArithmeticExceptionkann auftreten, wenn bei einer ganzzahligen Division der Divisor null ist. Diese Aussage betrifft die ganzzahlige Division; für die Division von Gleitkommazahlen durch null gelten in Java andere Regeln.
Diese Ausnahmen haben nicht alle dieselbe Ursache. Dass sie ungeprüft sind, bedeutet auch nicht, dass sie unmöglich zu behandeln wären. Prüfen Sie zunächst, ob sich der fehlerhafte Zustand verhindern lässt: Initialisieren und validieren Sie Referenzen, berechnen Sie Indizes anhand der Arraylänge und prüfen Sie den Divisor, wenn null für die betreffende Operation keine sinnvolle Eingabe ist. Ein Arrayindex ist beispielsweise gültig, wenn index >= 0 && index < numbers.length gilt.
Beispiel
Dieses vollständige Beispiel validiert jede Eingabe vor ihrer Verwendung und gibt die resultierenden Werte aus.
public class RuntimeExceptionExample {
public static void main(String[] args) {
String text = "Java";
int[] numbers = {10, 20, 30, 40, 50};
int index = 2;
int numerator = 12;
int denominator = 3;
if (text != null) {
System.out.println("Text length: " + text.length());
}
if (index >= 0 && index < numbers.length) {
System.out.println("Selected number: " + numbers[index]);
}
if (denominator != 0) {
System.out.println("Quotient: " + numerator / denominator);
}
}
}
Text length: 4
Selected number: 30
Quotient: 4
Die Zeichenkette ist vorhanden, der gewählte Index liegt innerhalb der Arraygrenzen und der Divisor ist ungleich null. Die hier beschriebenen Fälle mit Null-Dereferenzierung, ungültigem Arrayindex und Divisor null wurden nicht ausgeführt. Tritt einer dieser Fehler auf, wird die entsprechende Laufzeitausnahme ausgelöst. Wird eine Ausnahme nicht abgefangen, werden die Anweisungen nach dem fehlerhaften Vorgang in diesem Ausführungspfad nicht ausgeführt. Um jeden Fehler zu veranschaulichen, ändern Sie jeweils nur eine Eingabe und behandeln Sie den jeweiligen Fall einzeln. Mehrere nicht abgefangene Fehler hintereinander führen nicht dazu, dass jeder von ihnen erreicht wird.
Ein Abfangen kann sinnvoll sein, wenn das Programm dadurch eine konkrete Wiederherstellungsmaßnahme ausführen kann. Ein allgemeiner Catch-Block, der lediglich einen Programmierfehler verbirgt, erschwert jedoch die Fehlersuche. Validieren Sie Eingaben möglichst nahe an der Stelle, an der sie ins Programm gelangen, und beheben Sie die Ursache unerwarteter Zustände. Tests und Debugging helfen, solche Fehler zu finden; auch Codeanalysewerkzeuge können auf manche riskanten Muster hinweisen.
Unterschied zwischen java.lang.RuntimeException und java.lang.Exception
java.lang.RuntimeException ist eine Unterklasse von java.lang.Exception; jede Laufzeitausnahme ist also auch eine Ausnahme. java.lang.Exception umfasst jedoch ebenfalls Unterklassen, die geprüfte Ausnahmen sind und nicht von RuntimeException erben. Der praktische Unterschied liegt in den Anforderungen des Compilers und nicht darin, ob die Ursache extern ist oder ob eine Entwicklerin oder ein Entwickler die Ausnahme abfangen kann.
Eine geprüfte Ausnahme muss abgefangen oder in der throws-Klausel der Methode deklariert werden. Ruft ein Code beispielsweise eine API auf, die eine geprüfte Ausnahme deklariert, muss er diese Ausnahme berücksichtigen, damit der Code kompiliert. Bei einer ungeprüften Ausnahme wie NullPointerException verlangt Java kein entsprechendes Abfangen oder Deklarieren. Geprüfte und ungeprüfte Ausnahmen lassen sich beide mit try und catch abfangen. Eine Laufzeitausnahme abzufangen ist dann angemessen, wenn der Code eine nützliche und klar definierte Wiederherstellungsmaßnahme ausführen kann.
Error ist ein eigener Zweig unter Throwable und keine Unterklasse von Exception. Das hilft zu erklären, warum die Regeln des Compilers für geprüfte Ausnahmen auf Ausnahmetypen außerhalb der Unterklassen von RuntimeException und Error Anwendung finden.
Eine nicht abgefangene Ausnahme beendet den Thread, in dem sie auftritt. Entweicht sie aus dem Hauptthread, kann die Anwendung enden. Eine nicht abgefangene Ausnahme in einem anderen Thread bedeutet für sich genommen nicht, dass alle Threads beendet werden müssen. Die Behandlung sollte zum Fehler passen: Führen Sie eine Wiederherstellung durch, wenn das Programm dafür einen verlässlichen Weg bietet, und beheben Sie Fehler, die das Programm in einen unbeabsichtigten Zustand versetzen.
Fazit
java.lang.RuntimeException ist ungeprüft. Java verlangt daher nicht, dass sie abgefangen oder deklariert wird, obwohl sie abgefangen werden kann. Häufige Beispiele sind Null-Dereferenzierungen, ungültige Arrayindizes und die ganzzahlige Division durch null. Validieren Sie Werte und beheben Sie nach Möglichkeit den zugrunde liegenden Fehler. Verwenden Sie einen Catch-Block, wenn er eine klare Wiederherstellungsmaßnahme ermöglicht. Denken Sie daran: Eine nicht abgefangene Ausnahme beendet ihren Thread; die Auswirkungen auf die gesamte Anwendung hängen davon ab, welcher Thread betroffen ist.