【问题标题】:Throw an exception inside the method body and catch it after在方法体内抛出异常并在之后捕获它
【发布时间】:2014-08-20 18:46:56
【问题描述】:

主类:

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");
    }
}

输出:

finally
catch
finish

我不清楚这种行为。 JLS 8 的第 11.3 条说:

如果找不到可以处理异常的 catch 子句,则 当前线程(遇到异常的线程)是 终止。在终止之前,所有 finally 子句都被执行并且 未捕获的异常按照以下规则处理:

如果当前线程设置了未捕获的异常处理程序,那么 处理程序被执行。

否则,将为当前线程的父级> ThreadGroup 调用方法uncaughtException。如果 ThreadGroup 及其父 ThreadGroups 不覆盖 uncaughtException,然后调用默认处理程序的 uncaughtException 方法。

我预计输出将是finally,只是因为当前线程已终止。我没有产生任何其他线程,因为输出必须是finally,但事实并非如此。请帮我理解。

【问题讨论】:

    标签: java exception


    【解决方案1】:

    如果找不到可以处理异常的 catch 子句,[...]

    但是您确实有一个可以处理异常的catch 子句。由于抛出异常,您的 m 方法将突然完成。 The exception will be caught and handled 在您的 main 方法中,然后将与主线程一起正常完成。

    【讨论】:

    • 但是catch属于不同的try语句,它出现在main()方法内部,而不是m()内部。
    • @DmitryFucintv 在try 语句中引发的任何异常都可能被相应的catch 块捕获,无论异常被引发的调用堆栈有多远。
    【解决方案2】:

    通过将函数替换为其中的代码,这样查看可能更容易。

    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");
        }
    }
    

    【讨论】:

      【解决方案3】:

      以下是流程:

          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");
              }
          }
      

      只有在没有处理异常的情况下才会终止线程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 2018-12-22
        • 1970-01-01
        • 2020-02-13
        • 2012-09-15
        • 2010-09-13
        • 1970-01-01
        相关资源
        最近更新 更多