【问题标题】:Why this code is coming first in finally and then catch block?为什么这段代码首先出现在 finally 然后是 catch 块?
【发布时间】:2017-03-26 08:02:44
【问题描述】:
package testing;

public class ExceptionHandling {
    public static void main(String[] args){
        try{
        int a=10;
        int b=0;
        int c=a/b;
        ExceptionHandling exp = null;
        System.out.println(exp);
        throw new NullPointerException();

        }catch(ArithmeticException e){
            System.out.println("arithmetic issue");
            throw new ArithmeticException();
        }
        catch(NullPointerException e){
            System.out.println("nullpointer");

        }
        finally{

            System.out.println("exception");
            //throw new ArithmeticException();
        }

    }

}

在控制台中我得到了这个:

arithmetic issue
exception
Exception in thread "main" java.lang.ArithmeticException
    at testing.ExceptionHandling.main(ExceptionHandling.java:15)

但是为什么会先打印 finally 块语句,然后再打印 catch 块语句呢?它应该先打印 catch 块语句,然后打印 finally 块语句。

【问题讨论】:

  • 您的输出首先打印catch 块,然后是finally。为什么你认为它是打印的。
  • 检查这个答案。 link。此外,您不需要在 try 块本身中引发异常。

标签: java exception-handling finally


【解决方案1】:

控制台中的这一行:

Exception in thread "main" java.lang.ArithmeticException
    at testing.ExceptionHandling.main(ExceptionHandling.java:15)

没有从您的catch 块打印。它是在你的程序最终离开后打印出来的。

执行过程如下。

  1. try 出现异常。
  2. catch 捕获该异常。
  3. arithmetic issue 是从 catch 块打印出来的。
  4. 下一行重新抛出该异常。
  5. 你的程序即将离开catch,但在它离开之前,它会执行 finally 块的代码。这就是您在控制台中看到单词exception 的原因。这就是 finally 的工作原理。
  6. 最后,当您的程序最终离开此方法时,您会在控制台上看到实际异常。

【讨论】:

    【解决方案2】:

    流程是这样的:

    1. catch 语句捕获异常,打印消息但也再次抛出异常
    2. finally 块被执行,因此它的消息被打印出来
    3. 引发了catch 中引发的异常,因为从catch 无论如何都没有处理它

    【讨论】:

      【解决方案3】:

      它不会先运行,println 的工作方式与异常输出是并发的。所以他们可以按不同的顺序打印

      【讨论】:

      • 该输出与执行顺序一致。问题中没有观察到“各种顺序”。
      • @Andreas“输出与执行顺序一致”这是不正确的,我已经运行了上面的确切代码并有this(“异常”打印在错误处理的中间)但在这种情况下,我的回答也不正确。我的意思是执行顺序真的是他说的那样。
      【解决方案4】:

      main() 方法的异常 thrown 将由 JVM 处理 和 因为您已经在 catch 块中重新创建了 ArithmeticException 并从 main 方法中重新创建了 thrown ,所以 JVM 已经捕获了 ArithmeticExceptionmain() 方法抛出的main() 并打印出来控制台上的堆栈跟踪。

      你的程序流程如下:

      (1) ArithmeticException thrown 通过 try 块

      (2) ArithmeticException 已被catch 块捕获并重新创建了new ArithmeticExceptionthrown(通过此main() 方法)

      (3) finally 块已被执行并打印给定文本

      (4) main()方法抛出的ArithmeticException已被JVM捕获

      (5) JVM打印异常的stacktrace

      为了更好地理解这个概念,只需throw 来自不同方法的异常并从我的main() 中捕获它,如下所示:

          //myOwnMethod throws ArithmeticException
          public static void myOwnMethod() {
              try{
                  int a=10;
                  int b=0;
                  int c=a/b;
                  throw new NullPointerException();
              } catch(ArithmeticException e){
                  System.out.println("arithmetic issue");
                  throw new ArithmeticException();
              }
              catch(NullPointerException e){
                  System.out.println("nullpointer");
              }
              finally{
                  System.out.println("exception");
              }
          }
      
          //main() method catches ArithmeticException
          public static void main(String[] args) {
              try {
                  myOwnMethod();
              } catch(ArithmeticException exe) {
                  System.out.println(" catching exception from myOwnMethod()::");
                  exe.printStackTrace();
              }
          }
      

      但在您的情况下,您的 main() 已引发异常,并且 JVM 已捕获该异常。

      【讨论】:

        猜你喜欢
        • 2011-03-07
        • 2015-08-31
        • 2011-06-09
        • 1970-01-01
        • 2012-01-26
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        • 2014-08-27
        相关资源
        最近更新 更多