简体   繁体   中英

How does exception chain work in my code?

Why this code doesn't print "d". Why it doesn't go to the catch block for RunTimeException?

public static void main(String[] args) {
    System.out.println("a");
    try {
        System.out.println("b");
        throw new IllegalArgumentException();
    } catch (IllegalArgumentException e) {
        System.out.println("c");
        throw new RuntimeException();
    }catch (RuntimeException e) {
        System.out.println("d");
        throw new RuntimeException();
    }finally{
        System.out.println("e");
        throw new RuntimeException();
    }
}

The output of this program is

a
b
c
e
Exception in thread "main" java.lang.RuntimeException

EDIT: After throwing IllegalArgumentException it goes to the corresponding catch block and prints 'c'. after that since we don't catch the exception in RuntimeException it doesn't go any further. but since it's guranteed that we go to the finally block it print 'e' and after that throw RunttimeException. if the code was like something like the following, it would throw out the RuntimeException("2"). If we comment the exception inside finally, it throw out RuntimeException("1").

public static void main(String[] args) throws InterruptedException {
            System.out.println("a");
            try {
                System.out.println("b");
                throw new IllegalArgumentException();
            } catch (IllegalArgumentException e) {

                    System.out.println("c");
                    throw new RuntimeException("1");

            }catch (RuntimeException e) {
                System.out.println("d");
                throw new RuntimeException();
            }finally{
                System.out.println("e");
                throw new RuntimeException("2");
            }
        }

The catch blocks are NOT in the scope of the try . Any code in the catch blocks executes in the context of the outer main code, and thus has no exception handlers. When you throw RuntimeException the finally block for the try gets executed and then the exception terminates the program.

The reason of this code not printing d is, because in the IllegalArgumentException catch block, after printing "c" and before throwing RuntimeException it executes finally (that's how the flow works). Finally block throws exception itself, so It never gets to throw that RuntimeException that gets it to "d".

public static void main(String[] args) {
System.out.println("a");
try {
    System.out.println("b"); // 1
    throw new IllegalArgumentException(); // 2
} catch (IllegalArgumentException e) {
    System.out.println("c"); // 3
    throw new RuntimeException(); // nope, there's a finally block that executes first
}catch (RuntimeException e) {
    System.out.println("d");
    throw new RuntimeException();
}finally{
    System.out.println("e"); // 4
    throw new RuntimeException(); // 5 - rest of the code never got executed.
}

}

Hope this was clear enough.

Also, as It was pointed out, even if the RuntimeException after "c" was executed, It would not invoke the lower catch block. The catch block is only invoked once, depending on the Exception thrown in the try block (though this isn't really relevant because the first explanation dictates the flow of your thread).

In try catch block, if one of the catch block catches the exception the other catches doesn't get involved. remeber that finally block always run at the end no matter exception gets threw or not.

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