简体   繁体   中英

Throw an exception inside the method body and catch it after

The main class:

class IO 
{
    static void m() throws Exception
    {
        try
        {
            throw new Exception();
        } finally{
            System.out.println("finally");
        }
    }
    public static void main(String [] args) 
    {
        try {
            m();
        } catch (Exception ex) {
             System.out.println("catch");
        }
        System.out.println("finish");
    }
}

Output:

finally
catch
finish

That behavior is unclear for me. Clause 11.3 of JLS 8 says:

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:

If the current thread has an uncaught exception handler set, then that handler is executed.

Otherwise, the method uncaughtException is invoked for the ThreadGroup that is the parent > of the current thread. If the ThreadGroup and its parent ThreadGroups do not override uncaughtException, then the default handler's uncaughtException method is invoked.

I expected that the output will be finally only because current thread is terminated. I haven't produced any other threads, since the output must be finally , but it is not true. Help me to understand, please.

If no catch clause that can handle an exception can be found , [...]

But you do have a catch clause that can handle the exception. Your m method will complete abruptly as a result of the exception being thrown. The exception will be caught and handle d inside your main method which will then complete normally along with the main thread.

It might be easier to look at it like this, by replacing the function with the code from it.

class IO 
{
    public static void main(String [] args) 
    {
        try { //4 Now goes to the outer try
            try //2 Checks this try for the catch, but doesn't find it
            {
                throw new Exception(); //1 Hits the exception
            } finally{ //3 Executes this because there is no catch for this try
                System.out.println("finally");
            }
        } catch (Exception ex) { //5 Finds the catch
             System.out.println("catch");
        }
        //6 Continues as if nothing happened
        System.out.println("finish");
    }
}

The following is the flow:

    class IO 
    {
        static void m() throws Exception
        {
            try
            {   //2
                throw new Exception();
            } finally{
                    //3
                System.out.println("finally");
            }
        }
        public static void main(String [] args) 
        {
            try {
                m();//1 method called
            } catch (Exception ex) {
                  //4 the control returns
                 System.out.println("catch");
            }
                //5
            System.out.println("finish");
        }
    }

The thread is only terminated if the exception is not handled.

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