Unterschied zwischen java.lang.RuntimeException und java.lang.Exception

210

Jemand bitte erklären Sie den Unterschied zwischen java.lang.RuntimeExceptionund java.lang.Exception? Wie entscheide ich, welche ich erweitern möchte, wenn ich meine eigene Ausnahme erstelle?

cchampion
quelle

Antworten:

181

Im Allgemeinen sind RuntimeExceptions Ausnahmen , die programmgesteuert verhindert werden können. ZB NullPointerException, ArrayIndexOutOfBoundException. Wenn Sie nullvor dem Aufrufen einer Methode nach prüfen , NullPointerExceptionwürde dies niemals auftreten. Ähnliches ArrayIndexOutOfBoundExceptionwürde niemals passieren, wenn Sie zuerst den Index überprüfen. RuntimeExceptionwerden vom Compiler nicht überprüft, es handelt sich also um sauberen Code.

EDIT : Heutzutage bevorzugen RuntimeExceptiondie Leute den sauberen Code, den er erzeugt. Es ist eine ganz persönliche Entscheidung.

fastcodejava
quelle
10
Ich mag diesen Winkel von "Laufzeitausnahmen hätte vom Aufrufer vermieden werden können". Das heißt, Sie (als Aufrufer einer Methode) sollen sicherstellen, dass sie nicht einmal passieren. Während geprüfte Ausnahmen etwas sind, das Sie nicht vermeiden können und das Sie stattdessen nachträglich behandeln müssen. (Und ja, da nicht jeder mit dem Konzept der überprüften Ausnahmen einverstanden ist und viele Leute RuntimeException für alles verwenden, ist diese Unterscheidung etwas durcheinander geraten).
Thilo
4
Heutzutage bevorzugen die Leute auch die ungeprüfte RuntimeException, da sie mit der Java 8 Lambda-Verarbeitung kompatibel ist, während dies bei geprüften Ausnahmen vom Typ Exception nicht der Fall ist.
Hartmut P.
2
Ich vermute, der wahre Grund, warum Menschen fangen, RuntimeExceptionist, dass es einfach ist und die Notwendigkeit beseitigt, über die Unterschiede zwischen aktivierten und nicht aktivierten Ausnahmen nachzudenken. Ich denke, dass das Abfangen von Laufzeitausnahmen eine schreckliche Idee ist, da Sie nicht behebbare Ausnahmen wie z NullPointerException.
Dónal
186

In Java gibt es zwei Arten von Ausnahmen: geprüfte Ausnahmen und nicht geprüfte Ausnahmen. Eine geprüfte Ausnahme muss explizit vom Code behandelt werden, während eine nicht geprüfte Ausnahme nicht explizit behandelt werden muss.

Bei aktivierten Ausnahmen müssen Sie entweder einen try / catch-Block um den Code setzen, der möglicherweise die Ausnahme auslösen könnte, oder der Methode eine "throw" -Klausel hinzufügen, um anzugeben, dass die Methode möglicherweise diese Art von Ausnahme auslöst (was sein muss) in der aufrufenden Klasse oder höher behandelt).

Jede Ausnahme, die von "Ausnahme" abgeleitet ist, ist eine aktivierte Ausnahme, während eine Klasse, die von RuntimeException abgeleitet ist, nicht aktiviert ist. RuntimeExceptions müssen vom aufrufenden Code nicht explizit behandelt werden.

Andy White
quelle
3
Praktisch ist es wahr, dass "es zwei Arten von Ausnahmen gibt", aber warum sagt Oracle-Dokumentationen, dass es drei Arten gibt. Es betrachtet den Fehler als 3. Typ. Ich denke, Fehler ist überhaupt keine Ausnahme, es ist nur Throwable (Objekt), ja, es ahmt das Verhalten von Laufzeitausnahmen nach. Was würdest du dazu sagen? Oracle doc. ref. docs.oracle.com/javase/tutorial/essential/exceptions/…
Asif Shahzad
3
Ein Fehler soll nicht abgefangen werden (obwohl dies der Fall sein könnte). Im Allgemeinen verwenden Sie Fehler, um Ihre eigenen Fehler abzufangen, während Sie an neuem Code arbeiten. Wenn Sie beispielsweise eine if if / elseif-Anweisung für einen Baum haben, löst das letzte else möglicherweise nur einen Fehler aus ("Ich habe nicht erwartet, dass diese Bedingung eintritt"). Im Allgemeinen haben Ausnahmen Anwendungsfälle, in denen sie auftreten sollen, während Fehler keinen Anwendungsfall haben und ein Fehler sind.
Danny
5
Aber der Witz ist RunTimeException selbst erweitert Exception: D (Ich weiß, das macht keine Probleme und JVM kümmert sich um den gesamten Kontext)
Alireza Mohamadi
94

Bevor Sie den Unterschied zwischen java.lang.RuntimeExceptionund java.lang.ExceptionKlassen betrachten, müssen Sie die ExceptionHierarchie kennen. Beide Exceptionund ErrorKlassen werden von der Klasse abgeleitet Throwable(die von der Klasse abgeleitet ist Object). Und die Klasse RuntimeExceptionist von der Klasse abgeleitet Exception.

Alle Ausnahmen werden entweder von Exceptionoder abgeleitet RuntimeException.

Alle Ausnahmen, die sich daraus RuntimeExceptionergeben, werden als ungeprüfte Ausnahmen bezeichnet. Alle anderen Ausnahmen sind geprüfte Ausnahmen. Eine aktivierte Ausnahme muss irgendwo in Ihrem Code abgefangen werden, sonst wird sie nicht kompiliert. Deshalb werden sie als geprüfte Ausnahmen bezeichnet. Andererseits ist die aufrufende Methode mit ungeprüften Ausnahmen nicht verpflichtet, sie zu behandeln oder zu deklarieren.

Daher werden alle Ausnahmen, von denen der Compiler Sie zum Behandeln zwingt, direkt abgeleitet, java.lang.Exceptionund alle anderen, von denen der Compiler Sie nicht zum Behandeln zwingt, werden abgeleitet java.lang.RuntimeException.

Im Folgenden sind einige der direkt bekannten Unterklassen von RuntimeException aufgeführt .

AnnotationTypeMismatchException,
ArithmeticException,
ArrayStoreException,
BufferOverflowException,
BufferUnderflowException,
CannotRedoException,
CannotUndoException,
ClassCastException,
CMMException,
ConcurrentModificationException,
DataBindingException,
DOMException,
EmptyStackException,
EnumConstantNotPresentException,
EventException,
IllegalArgumentException,
IllegalMonitorStateException,
IllegalPathStateException,
IllegalStateException,
ImagingOpException,
IncompleteAnnotationException,
IndexOutOfBoundsException,
JMRuntimeException,
LSException,
MalformedParameterizedTypeException,
MirroredTypeException,
MirroredTypesException,
MissingResourceException,
NegativeArraySizeException,
NoSuchElementException,
NoSuchMechanismException,
NullPointerException,
ProfileDataException,
ProviderException,
RasterFormatException,
RejectedExecutionException,
SecurityException,
SystemException,
TypeConstraintException,
TypeNotPresentException,
UndeclaredThrowableException,
UnknownAnnotationValueException,
UnknownElementException,
UnknownTypeException,
UnmodifiableSetException,
UnsupportedOperationException,
WebServiceException 
GAJJE82
quelle
47

Eine Ausnahme ist aktiviert und eine RuntimeException ist deaktiviert.

Aktiviert bedeutet, dass der Compiler verlangt, dass Sie die Ausnahme in einem Catch behandeln oder Ihre Methode als Auslöser (oder eine ihrer Oberklassen) deklarieren.

Im Allgemeinen wird eine aktivierte Ausnahme ausgelöst, wenn vom Aufrufer der API erwartet wird, dass sie die Ausnahme behandelt, und eine nicht aktivierte Ausnahme, wenn dies normalerweise vom Aufrufer nicht behandelt werden kann, z. B. ein Fehler mit einem der Parameter, z. B. eine Programmierung Fehler.

Lawrence Dol
quelle
15

Die Laufzeitausnahmeklassen (RuntimeException und ihre Unterklassen) sind von der Überprüfung der Kompilierungszeit ausgenommen, da der Compiler nicht feststellen kann, dass Laufzeitausnahmen nicht auftreten können. (von JLS).

In den von Ihnen entworfenen Klassen sollten Sie Exception unterordnen und Instanzen davon auslösen, um außergewöhnliche Szenarien zu signalisieren. Auf diese Weise signalisieren Sie den Clients Ihrer Klasse explizit, dass die Verwendung Ihrer Klasse möglicherweise eine Ausnahme auslöst, und sie müssen Schritte unternehmen, um diese Ausnahmeszenarien zu behandeln.

Die folgenden Codeausschnitte erläutern diesen Punkt:

//Create your own exception class subclassing from Exception
class MyException extends Exception {
    public MyException(final String message) {
        super(message);
    }
}

public class Process {
    public void execute() {
        throw new RuntimeException("Runtime");
    }  
    public void process() throws MyException {
        throw new MyException("Checked");
    }
}

In der obigen Klassendefinition der Klasse Process kann die Methode executeeine RuntimeException auslösen , die Methodendeklaration muss jedoch nicht angeben, dass sie RuntimeException auslöst .

Die Methode löstprocess eine aktivierte Ausnahme aus und sollte deklarieren, dass eine aktivierte Ausnahme der Art MyException ausgelöst wird. Andernfalls wird ein Kompilierungsfehler angezeigt .

Die obige Klassendefinition wirkt sich auch auf den Code aus, der die Prozessklasse verwendet .

Der Aufruf new Process().execute()ist ein gültiger Aufruf, bei dem der Aufruf der Form new Process().process()einen Kompilierungsfehler ergibt. Dies liegt daran, dass der Client-Code Schritte zur Behandlung ausführen sollte MyException(z. B. kann call to process () in einen try / catch-Block eingeschlossen werden).

Sateesh
quelle
13

Richtige Verwendung von RuntimeException?

Von ungeprüften Ausnahmen - Die Kontroverse :

Wenn von einem Client vernünftigerweise erwartet werden kann, dass er sich von einer Ausnahme erholt, machen Sie ihn zu einer aktivierten Ausnahme. Wenn ein Client nichts tun kann, um die Ausnahme zu beheben, machen Sie es zu einer nicht aktivierten Ausnahme.

Beachten Sie, dass eine nicht aktivierte Ausnahme von einer abgeleiteten RuntimeExceptionund eine aktivierte von einer abgeleiteten Ausnahme abgeleitet ist Exception.

Warum einen werfen, RuntimeExceptionwenn ein Client nichts tun kann, um die Ausnahme zu beheben? Der Artikel erklärt:

Laufzeitausnahmen stellen Probleme dar, die das Ergebnis eines Programmierproblems sind, und daher kann nicht vernünftigerweise erwartet werden, dass der API-Clientcode von ihnen wiederhergestellt oder in irgendeiner Weise behandelt wird. Solche Probleme umfassen arithmetische Ausnahmen, wie das Teilen durch Null; Zeigerausnahmen, z. B. der Versuch, über eine Nullreferenz auf ein Objekt zuzugreifen; und Indizieren von Ausnahmen, z. B. der Versuch, über einen zu großen oder zu kleinen Index auf ein Array-Element zuzugreifen.

Mahdi Esmaeili
quelle
5

Aus der Orakel-Dokumentation:

Hier ist die grundlegende Richtlinie: Wenn von einem Client vernünftigerweise erwartet werden kann, dass er sich von einer Ausnahme erholt, machen Sie ihn zu einer aktivierten Ausnahme. Wenn ein Client nichts tun kann, um die Ausnahme zu beheben, machen Sie es zu einer nicht aktivierten Ausnahme.

Laufzeitausnahmen stellen Probleme dar, die das Ergebnis eines Programmierproblems sind, und daher kann nicht erwartet werden, dass der API-Clientcode diese wiederherstellt oder in irgendeiner Weise behandelt.

RuntimeExceptions sind wie "Ausnahmen durch ungültige Verwendung einer API" Beispiele für Laufzeitausnahmen: IllegalStateException, NegativeArraySizeException, NullpointerException

Mit den Ausnahmen müssen Sie es explizit abfangen, da Sie noch etwas tun können, um sich zu erholen. Beispiele für Ausnahmen sind: IOException, TimeoutException, PrintException ...

iberck
quelle
4

In einfachen Worten, wenn Ihr Kunde / Benutzer aus dem Exception wiederherstellen kann dann macht es zu einer überprüft Ausnahme , wenn Ihr Kunde nichts von der Ausnahme erholen tun kann , dann macht es Ungeprüfter Runtime . Beispielsweise wäre eine RuntimeException ein programmatischer Fehler, wie die Division durch Null. Kein Benutzer kann etwas dagegen tun, außer der Programmierer selbst. Dann handelt es sich um eine RuntimeException .

Joe Almore
quelle
3

RuntimeException ist eine untergeordnete Klasse der Exception-Klasse

Dies ist eine der vielen untergeordneten Klassen der Ausnahmeklasse. RuntimeException ist die Oberklasse der Ausnahmen, die während des normalen Betriebs der Java Virtual Machine ausgelöst werden können. Eine Methode muss in ihrer throw-Klausel keine Unterklassen von RuntimeException deklarieren, die möglicherweise während der Ausführung der Methode ausgelöst, aber nicht abgefangen werden.

Die Hierarchie ist

java.lang.Object

--- java.lang.Throwable

------- java.lang.Exception

------------- java.lang.RuntimeException

jayrhd
quelle
0

Ausnahmen sind eine gute Möglichkeit, um unerwartete Ereignisse in Ihrem Anwendungsfluss zu behandeln. RuntimeException wird vom Compiler deaktiviert. Möglicherweise bevorzugen Sie jedoch die Verwendung von Ausnahmen, die die Ausnahmeklasse erweitern, um das Verhalten Ihrer API-Clients zu steuern, da diese Fehler abfangen müssen, damit sie kompiliert werden können. Bildet auch eine gute Dokumentation.

Wenn Sie eine saubere Schnittstelle erreichen möchten, verwenden Sie die Vererbung, um die verschiedenen Ausnahmetypen Ihrer Anwendung zu unterklassifizieren und dann die übergeordnete Ausnahme verfügbar zu machen.

FOO
quelle
0

Es gibt zwei Arten von Ausnahmen: Sie können eine aktivierte Ausnahme wiederherstellen, wenn Sie eine solche Ausnahme erhalten. Laufzeitausnahmen sind nicht behebbar, Laufzeitausnahmen sind Programmierfehler, und der Programmierer sollte sich beim Schreiben des Codes darum kümmern. Wenn Sie die Ausführung fortsetzen, erhalten Sie möglicherweise ein falsches Ergebnis. Bei Laufzeitausnahmen geht es um die Verletzung der Vorbedingung ex. Wenn Sie ein Array der Größe 10 haben und versuchen, auf das 11. Element zuzugreifen, wird ArrayIndexOutOfBoundException ausgelöst

Bhagwati Malav
quelle
0
  1. Benutzerdefinierte Ausnahmen können "Checked Exception" oder "Unchecked Exception" sein. Dies hängt von der Klasse ab, auf die sie erweitert werden.

  2. Benutzerdefinierte Ausnahmen können benutzerdefinierte geprüfte Ausnahmen sein, wenn sie sich auf die Ausnahmeklasse erstrecken

  3. Benutzerdefinierte Ausnahmen können benutzerdefinierte nicht aktivierte Ausnahmen sein, wenn sie sich auf die Laufzeitausnahmeklasse erstrecken.

  4. Definieren Sie eine Klasse und machen Sie sie zu einem Kind der Ausnahme oder der Laufzeitausnahme

Aditya
quelle