Warum ist beim Aufrufen einer Funktion "löst eine Ausnahme aus" erforderlich?

96
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

Warum Compiler Berichte , dass Methoden show2(), show3()und main()haben

nicht gemeldete Ausnahme Ausnahme, die abgefangen oder deklariert werden muss, um ausgelöst zu werden

Wann entferne ich throws Exceptionvon diesen Methoden?

nr5
quelle
2
@PaulTomblin main kann sicherlich als Ausnahme deklariert werden. In diesem Fall wird die JVM heruntergefahren. Dies ist so nahe daran, es zu ignorieren, wie es der Compiler zulässt.
Taymon
Wenn die aufgerufene Methode ( Methdod1 ) ausgelöst wirdException , müssen wir die aufrufende Methode ( Methode2 ) mit definieren throws Exception; wenn wir diese Ausnahme nicht in der aufrufenden Methode übergeben. Der Zweck dieses Vorgangs besteht darin, der aufrufenden Methode ( Methode3 ) von Methode2 mitzuteilen, dass eine Ausnahme von Methode2 ausgelöst werden kann, und Sie sollten sie hier behandeln, da sie sonst Ihr Programm unterbrechen kann.
Rito
Wenn Methode3 die Ausnahme in ihrem Hauptteil nicht behandelt, musste sie throws Exceptionin ihrer Methodendefinition definieren, um die aufrufende Methode aufzugeben. Erweiterung des vorherigen Kommentars
Rito

Antworten:

142

Wie Sie vielleicht wissen, können Ausnahmen in Java in zwei Kategorien eingeteilt werden: Eine, die die throwsKlausel benötigt oder behandelt werden muss, wenn Sie keine angeben, und eine andere, die dies nicht tut. Sehen Sie sich nun die folgende Abbildung an:

Geben Sie hier die Bildbeschreibung ein

In Java können Sie alles werfen, was die ThrowableKlasse erweitert. Sie müssen jedoch nicht throwsfür alle Klassen eine Klausel angeben . Im einzelnen Klassen, die entweder ein Erroroder RuntimeExceptionoder irgendeine der Subklassen von diesen beiden. In Ihrem Fall Exceptionhandelt es sich nicht um eine Unterklasse eines Erroroder RuntimeException. Es handelt sich also um eine aktivierte Ausnahme, die in der throwsKlausel angegeben werden muss , wenn Sie diese bestimmte Ausnahme nicht behandeln. Deshalb brauchten Sie die throwsKlausel.


Aus dem Java-Tutorial :

Eine Ausnahme ist ein Ereignis, das während der Ausführung eines Programms auftritt und den normalen Ablauf der Programmanweisungen stört.

Wie Sie wissen, werden Ausnahmen in zwei Kategorien eingeteilt: aktiviert und deaktiviert. Warum diese Klassifizierung?

Überprüfte Ausnahme: Sie werden verwendet, um Probleme darzustellen, die während der Ausführung des Programms behoben werden können. Sie sind normalerweise nicht die Schuld des Programmierers. Beispielsweise ist eine vom Benutzer angegebene Datei nicht lesbar oder es ist keine Netzwerkverbindung verfügbar usw. In all diesen Fällen muss unser Programm nicht beendet werden, sondern kann Aktionen wie das Benachrichtigen des Benutzers oder einen Fallback ausführen Mechanismus (wie Offline-Arbeiten, wenn das Netzwerk nicht verfügbar ist) usw.

Nicht aktivierte Ausnahmen: Sie können wiederum in zwei Bereiche unterteilt werden: Fehler und RuntimeExceptions. Ein Grund dafür, dass sie nicht aktiviert sind, besteht darin, dass sie zahlreich sind und für die Handhabung aller Programme unser Programm überladen und seine Klarheit verringern müssen. Der andere Grund ist:

  • Laufzeitausnahmen: Sie treten normalerweise aufgrund eines Fehlers des Programmierers auf. Wenn beispielsweise eine ArithmeticExceptionDivision durch Null auftritt oder eine ArrayIndexOutOfBoundsExceptionauftritt, liegt dies daran, dass wir bei unserer Codierung nicht vorsichtig genug sind. Sie treten normalerweise aufgrund einiger Fehler in unserer Programmlogik auf. Sie müssen also gelöscht werden, bevor unser Programm in den Produktionsmodus wechselt. Sie sind in dem Sinne deaktiviert, dass unser Programm bei Auftreten fehlschlagen muss, damit wir Programmierer es zum Zeitpunkt der Entwicklung und des Testens selbst beheben können.

  • Fehler: Fehler sind Situationen, aus denen das Programm normalerweise keine Wiederherstellung durchführen kann. Wenn beispielsweise a StackOverflowErrorauftritt, kann unser Programm nicht viel tun, z. B. den Funktionsaufrufstapel des Programms vergrößern. In diesem Fall OutOfMemoryErrorkönnen wir nicht viel tun, um die für unser Programm verfügbare RAM-Größe zu erhöhen. In solchen Fällen ist es besser, das Programm zu beenden. Deshalb werden sie deaktiviert.

Detaillierte Informationen finden Sie unter:

Jomoos
quelle
Was ich aus Ihrer Antwort erhalten habe, ist, dass die Error-Klasse und ihre Unterklassen sowie die RuntimeException-Klasse und ihre Unterklassen unter eine ungeprüfte Ausnahme fallen (wie System.out.println (5/0); es besteht keine Notwendigkeit zu werfen, da es sich um eine handelt Laufzeitausnahme, aber wir können trotzdem try catch anwenden) und die Exception-Klasse ist aktiviert, daher müssen wir die
throw-
Noch eine Frage: Wenn die Ausnahmen in ungeprüft und geprüft kategorisiert sind, insbesondere in die ungeprüften (Laufzeitfehler), um mehr Fehler während der Kompilierungszeit zu vermeiden?
Nr. 5
@Jomoos - Angenommen, der Code in einer Methode löst eine IOException aus. Ist es dann in Ordnung, "Throws Exception" in die Deklaration der Methode aufzunehmen?
MasterJoe
Oh. Ich verstehe es jetzt. Es gibt eine Ausnahme zu den Regeln der Ausnahmehierarchie. Macht. Perfekt. Sinn. Danke Java.
JJS
25

Java erfordert, dass Sie alle Ausnahmen behandeln oder deklarieren. Wenn Sie eine Ausnahme nicht mit einem try / catch-Block behandeln, muss sie in der Signatur der Methode deklariert werden.

Beispielsweise:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

Sollte geschrieben werden als:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

Auf diese Weise können Sie die Deklaration "throw Exception" in der Methodendeklaration entfernen.

jebar8
quelle
7
Alle Ausnahmen, die keine Unterklassen von sind RuntimeException, das heißt.
Yshavit
Wenn es eine andere Klasse wie Exception gibt, die überprüft wird?
Nr. 5
1
Was meinst du? Da alle Ausnahmeobjekte "Ausnahme" als Basisklasse haben, wird beim Abfangen eines "Ausnahme" -Objekts (wie in meinem Beispiel) jede ausgelöste Ausnahme abgefangen. Um genauer zu sein (da unterschiedliche Ausnahmen wahrscheinlich unterschiedliche Arten der Handhabung erfordern), sollten Sie mehrere Fangblöcke haben.
jebar8
Wenn ich sagen würde, dass geprüfte Ausnahmen zur Kompilierungszeit behandelt und zur Laufzeit abgefangen werden müssen. Habe ich recht ? Wenn ja, wäre es dann, denselben Satz für eine ungeprüfte Ausnahme zu formulieren?
Nr. 5
@ jebar8 - Sie verwechseln Java mit .NET - in Java müssen Throwables erben Throwable(das Erben Exceptionfunktioniert auch, da es erweitert wird Throwable, aber nicht erforderlich ist).
BrainSlugs83
4

Exceptionist eine geprüfte Ausnahmeklasse. Daher jeder Code, der eine Methode aufruft, die deklariert, dass sie damit throws Exceptionumgehen oder deklarieren muss.

Taymon
quelle
Jede Methode in der Kette wird als Ausnahme deklariert, einschließlich main. Wo ist das Problem?
Paul Tomblin
@PaulTomblin Ich frage, warum es notwendig ist, Auslösungen in die aufrufenden Funktionen zu schreiben und eine Funktion aufzurufen, die eine Ausnahme
auslöst
Ok, ich habe nicht verstanden, warum Sie nach einem Compilerfehler gefragt haben, den Sie nicht aus dem von Ihnen geposteten Code erhalten haben. Das ist eine seltsame Art zu fragen.
Paul Tomblin
4

Die throws ExceptionDeklaration ist eine automatisierte Methode, um Methoden zu verfolgen, die aus erwarteten, aber unvermeidbaren Gründen eine Ausnahme auslösen können. Die Deklaration ist in der Regel spezifisch für den Typ oder die Arten von Ausnahmen, die ausgelöst werden können, wie z. B. throws IOExceptionoder throws IOException, MyException.

Wir alle haben oder werden irgendwann Code schreiben, der unerwartet stoppt und eine Ausnahme aufgrund von etwas meldet, das wir vor dem Ausführen des Programms nicht erwartet hatten, wie z. B. Division durch Null oder Index außerhalb der Grenzen. Da die Fehler von der Methode nicht erwartet wurden, konnten sie nicht "abgefangen" und mit einer try catch-Klausel behandelt werden. Alle ahnungslosen Benutzer der Methode würden diese Möglichkeit ebenfalls nicht kennen und ihre Programme würden ebenfalls aufhören.

Wenn der Programmierer weiß, dass bestimmte Arten von Fehlern auftreten können, diese Ausnahmen jedoch außerhalb der Methode behandeln möchten, kann die Methode eine oder mehrere Arten von Ausnahmen für die aufrufende Methode "auslösen", anstatt sie zu behandeln. Wenn der Programmierer nicht deklariert hat, dass die Methode eine Ausnahme auslösen könnte (oder wenn Java nicht in der Lage wäre, sie zu deklarieren), könnte der Compiler dies nicht wissen und es wäre Sache des zukünftigen Benutzers der Methode, darüber Bescheid zu wissen. Fangen und behandeln Sie alle Ausnahmen, die die Methode möglicherweise auslöst. Da Programme viele Ebenen von Methoden haben können, die von vielen verschiedenen Programmen geschrieben wurden, wird es schwierig (unmöglich) zu verfolgen, welche Methoden Ausnahmen auslösen könnten.

Obwohl Java Ausnahmen deklarieren kann, können Sie dennoch eine neue Methode mit nicht behandelten und nicht deklarierten Ausnahmen schreiben. Java kompiliert sie und Sie können sie ausführen und auf das Beste hoffen. Java lässt Sie Ihre neue Methode nicht kompilieren, wenn es eine Methode verwendet, die als auslösende Ausnahme (n) deklariert wurde, es sei denn, Sie behandeln entweder die deklarierten Ausnahmen in Ihrer Methode oder deklarieren Ihre Methode als auslösende (n) Ausnahme (n) oder wenn es mehrere Ausnahmen gibt, können Sie einige behandeln und den Rest werfen.

Wenn ein Programmierer erklärt, dass die Methode einen bestimmten Ausnahmetyp auslöst, ist dies nur eine automatisierte Methode, um andere Programmierer mit der Methode zu warnen, dass eine Ausnahme möglich ist. Der Programmierer kann dann entscheiden, die Ausnahme zu behandeln oder die Warnung weiterzuleiten, indem er erklärt, dass die aufrufende Methode dieselbe Ausnahme auslöst. Da der Compiler gewarnt wurde, dass die Ausnahme bei dieser neuen Methode möglich ist, kann er automatisch prüfen, ob zukünftige Aufrufer der neuen Methode die Ausnahme behandeln oder deklarieren und das eine oder andere erzwingen.

Das Schöne an dieser Art von Lösung ist, dass der Compiler beim Melden Error: Unhandled exception type java.io.IOExceptiondie Datei- und Zeilennummer der Methode angibt , die zum Auslösen der Ausnahme deklariert wurde. Sie können dann einfach das Geld übergeben und deklarieren, dass Ihre Methode auch "IOException auslöst". Dies kann bis zur Hauptmethode erfolgen, bei der das Programm dann angehalten und die Ausnahme dem Benutzer gemeldet wird. Es ist jedoch besser, die Ausnahme abzufangen und auf nette Weise damit umzugehen, z. B. dem Benutzer zu erklären, was passiert ist und wie sie behoben werden kann. Wenn eine Methode die Ausnahme abfängt und behandelt, muss sie die Ausnahme nicht mehr deklarieren. Das Geld bleibt sozusagen dort stehen.

Dansalmo
quelle
0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

Nur kleine Änderungen in Ihrem Programm. Was von vielen in Bezug auf das Hauptproblem missverstanden zu werden scheint, ist, wann immer Sie eine Ausnahme auslösen, die Sie behandeln müssen, nicht an derselben Stelle erforderlich (z. B. show1,2,3-Methode in Ihrem Programm), aber Sie müssen zuerst die Methode aufrufen innerhalb der 'Haupt'. Mit einem Wort, es gibt 'werfen', es muss 'fangen / versuchen' geben, auch wenn nicht dieselbe Methode, bei der eine Ausnahme auftritt.

Tawess
quelle
0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Da in der show () -Methode eine Ausnahme geprüft ist, die in dieser Methode nicht behandelt wird, verwenden wir das Schlüsselwort throw, um die Ausnahme weiterzugeben.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Da Sie die show () -Methode in der show2 () -Methode verwenden und mindestens die Ausnahme propagiert haben, sollten Sie hier behandeln. Wenn Sie die Ausnahme hier nicht behandeln, verwenden Sie das Schlüsselwort throw. Dies ist der Grund für die Verwendung des Schlüsselworts throw bei der Methodensignatur.

Aditya
quelle
0

Wenn Sie die Ausnahme weitergeben, indem Sie die Throws-Direktive in der Signatur der aktuellen Methode deklarieren, muss irgendwo in der Zeile oder im Aufrufstapel ein try / catch-Konstrukt verwendet werden, um die Ausnahme zu behandeln.

Beaumont Muni
quelle
Dieser Kommentar sollte dem Kommentarbereich hinzugefügt werden, da er keine überprüfbare Antwort oder ein Beispiel dafür enthält. - stackoverflow.com/help/how-to-answer
Paul Dawson
-1

Wenn Sie die Ausnahme nicht an derselben Stelle behandeln, an der Sie sie auslösen, können Sie bei der Definition der Funktion grundsätzlich "Ausnahme auslösen" verwenden.

Shahzeb Sheikh
quelle