【问题标题】:How it is decided which catch block comes first?如何决定哪个 catch 块先出现?
【发布时间】:2017-02-12 11:20:29
【问题描述】:

catch 块是如何决定的?

try{  
    int a[]=new int[5];  
    a[5]=30/0;  
}  
catch(ArithmeticException e){System.out.println("task1 is completed");}  
catch(ArrayIndexOutOfBoundsException e){System.out.println("task 2 completed");}  
catch(Exception e){System.out.println("common task completed");}  

我只知道派生类在前,基类紧随其后。 ArithmeticExceptionArrayIndexOutOfBoundsException 类来自:

java.lang.Exception
    java.lang.RuntimeException
        java.lang.ArithmeticException 

java.lang.Exception
    java.lang.RuntimeException
        java.lang.IndexOutOfBoundsException
            java.lang.ArrayIndexOutOfBoundsException 

为什么ArithmeticException放在第一位?

【问题讨论】:

  • “为什么ArithmeticException放在第一位?”没有理由。 ArithmeticExceptionArrayIndexOutOfBoundsException 可以按任意顺序排列,只要它们都在 Exception 之前。

标签: java exception try-catch


【解决方案1】:

它们按照您提供的顺序进行测试:第一个 catch 的类型是要抛出的异常的类或其超类是使用的类型。这在JLS§14.20.1 中有描述:

  • 如果 try 块的执行由于抛出值 V 而突然完成,那么有一个选择:

    • 如果 V 的运行时类型与 try 语句的任何 catch 子句的可捕获异常类的赋值兼容(第 5.2 节),则选择第一个(最左侧)这样的 catch 子句。将值V赋给选中的catch子句的参数,执行那个catch子句的Block,然后有一个选择:

      • 如果该块正常完成,则try 语句正常完成。

      • 如果该块由于某种原因突然完成,那么try 语句也会出于同样的原因而突然完成。

    • 如果 V 的运行时类型与 try 语句的任何 catch 子句的可捕获异常类的赋值不兼容,则 try 语句会由于值 V 的抛出而突然完成.

继续您的问题...

为什么ArithmeticException放在第一位?

因为那是该代码的作者想要做的。在该代码中,将ArithmeticExceptionIndexOutOfBoundsExceptioncatch 放在首位并不重要,因为它们是类型层次结构中的不同分支;抛出的任何异常都与它们的赋值兼容,因此前两个 catch 块的顺序无关紧要。 第三个​​ 但是,需要在结束,因为 ArithmeticExceptionIndexOutOfBoundsException 都与 Exception 分配兼容。

【讨论】:

    【解决方案2】:

    我相信它是第一个匹配的,而不是“最具体的”。

    例如,如果你先有 catch(Exception e),其余的甚至都看不到。

    【讨论】:

    • 这个应该是评论
    • 好吧,当我获得足够的声誉来实际为原始问题添加评论时,我会的。责备某人在没有代表这样做时不发表评论有点居高临下。我必须提供首先获得投票的答案。
    • 我不想那样做。我能理解你的痛苦!我只是发表了评论,以便您可以使其更详细和更具解释性,以便它做出回答。如果你这样做,我会投票!
    • 对不起。只是因为回答而不是评论,我被“责骂”了 2/2。
    【解决方案3】:

    它是顺序和类型匹配的组合。 执行第一个匹配异常类型的 catch 块。

    【讨论】:

      【解决方案4】:

      ArithmetcException 在任何静态意义上都没有放在首位。您观察到的行为更多地与赋值表达式的评估有关:在赋值中,右侧在任何左侧之前被完全评估。

      因此在尝试错误的数组访问之前尝试除以零 - 并引发相关异常。

      因此您的代码不会抛出与数组越界访问相关的异常。

      【讨论】:

        【解决方案5】:

        你可以交换上面提到的两个catch子句,结果是一样的。

        由于 ArithmeticExceptionArrayIndexOutOfBoundsException 之间没有直接的层次关系,所以没有关系。异常控制从 try 块线性流动。

        另外,请确保您执行的调试打印在其中包含一些语义,而不仅仅是“任务 1 已完成”...如果这只是一个测试 sn-p 而不是长期运行的一部分,请忽略上述语句项目。

        【讨论】:

          猜你喜欢
          • 2011-07-11
          • 2016-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-12
          • 1970-01-01
          • 2021-09-21
          相关资源
          最近更新 更多