简体   繁体   中英

Handling with the checked exception from main method

public class s1 {

    void m1(){
        m2();
    }

    String m2() throws IOException{
        BufferedReader inputFile = new BufferedReader(new FileReader("a.txt"));
        String line = inputFile.readLine();
        inputFile.close();
        return line;
    }
}


public class Main {
    public static void main(String[] args) {
        s1 obj1 = new s1();
        try {
            obj1.m1();
        }
        catch (Exception e){
            System.out.println("I got it!");
        }
    }
}

When I run this code , I got

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type IOException

I am confused about that message , because I thought that I handled with this checked IOException in the main method.Yet , the compiler wants me to add throws to the void m1() as well.What is the main reason of this ?

The method m2 called by m1 throws an exception. So you should either:

Add throws IOException to the method m1

or

Call the method m2 inside a try block

Because something has to be done with the exception thrown by m2, either to be caught on to be thrown again.

Your method m1 calls another method m2 which throws the exception, so m1 must throw it aswell, that's how Java was designed.

If you used try/catch in method m2 to catch that exception, you wouldn't need to add throws to it. So if you don't want to add throws IOException to m2 and everything that calls m2 - catch it immediately in this method.

the compiler wants me to add throws to the void m1() as well. What is the main reason of this ?

There are two main aspects of exception handling, reporting and recovering . In Java exception handling provides a flexible mechanism for passing control from the point of error reporting to a complement recovery handler.

The throws clause signals the caller of your method that it may encounter a IOException . Then the caller needs to make the same decision, handle the exception or tell its caller that the exception may be thrown.

To put it simply, If a method is using throws clause then this implicitly tells the other methods – "If you call me, you must handle these exceptions that I throw".

The method m2 may throw an IOException .
Since m1 calls m2 , also m1 may throw that exception.
IOException does not derive from RuntimeException so the fact it may be thrown should be declared explicitely.
In other words, add throws IOException to the declaration of m1 .

Any method invoking another method which throws any Checked exception must either Handle them or throw them. If not handled by catching then in the signature of the method the exception must be declared so that any caller of such method is aware of the exception to be handled. Checked Exception are intentional for some exceptional case and must be handled or thrown. In your case as m2() throws a checkedException and m1() calls m2() hence it is responsibility of the Signature of the method of m1() to let any caller of m1() know that there is a possibility of an exceptional case that must be handled. Note that in your case you are just invoking it from main method but that does not prevent you or any other developer from invoking it from any other method in future . It is responsibility of the method throwing the checked exception to declare that an exceptional case exists and needs to be handled, the callers just handle them.

Hope now you understand that you need to modify the signature of m1() and add the missing declaration for the IOException .

Let see what the JLS: 11.3. Run-Time Handling of an Exception says.

When an exception is thrown (§14.18), control is transferred from the code that caused the exception to the nearest dynamically enclosing catch clause, if any, of a try statement (§14.20) that can handle the exception.

...

If no catch clause that can handle an exception can be found, then the current thread (the thread that encountered the exception) is terminated. Before termination, all finally clauses are executed and the uncaught exception is handled according to the following rules:

And after the example :

The declaration of the method thrower must have a throws clause because it can throw instances of TestException, which is a checked exception class (§11.1.1). A compile-time error would occur if the throws clause were omitted.

This last statement is exactly your case, m1 is omitting the throws clause, so a compile-time error occurs. Add a throws IOException or any super class/interface of this Exception to correct this error.

Note : It is interesting to note that, if you try to catch a IOException from the main with you actual code, you will get an other compile-time error for trying to catch a unthrowned exception. But this is not the case with Exception since this only occurs with checked exception , since Exception can but an unchecked exception with RuntimeException , this is not the case.

More information in JLS : 11.2. Compile-Time Checking of Exceptions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM