【问题标题】:Supertype and subtype exception handling超类型和子类型异常处理
【发布时间】:2014-12-02 10:49:37
【问题描述】:

考虑这段代码:

public class CheckException 
{
    public static void main(String [] args)
    {       
       int a = 10;
        try{
            int c = a/0;
        } catch(Exception e){

        } catch(ArithmeticException e1){    \\ compilation error

        }
    }   
}

我怀疑在第二次捕获时会生成编译错误,因为它已经由超类型异常处理。但是为什么当第二个 catch 块到达第一个位置并且第一个到达第二个位置时(如下所示)没有出现编译错误?

public class CheckException {

public static void main(String [] args){

    int a = 10;
    try{
        int c = a/0;
    } catch(ArithmeticException e){
//       System.out.println("1");   
    } 
    catch(Exception e1){
//          System.out.println("2");
    }
}

}

那么第一个块(即 ArithmeticException)也会在异常到达 catch(Exception e) 之前处理它。

修改

现在我在 catch(Exception e) 之前添加所有未经检查的异常。

public class CheckException {

public static void main(String [] args){

    int a = 10;
    try{
        int c = a/0;
    } catch(ArithmeticException e){
     System.out.println("1");   
    } 
    catch(ArrayIndexOutOfBoundsException e1){
        System.out.println("2");
    }
    catch(ClassCastException  e1){
        System.out.println("2");
    }
    catch(IllegalArgumentException  e1){
        System.out.println("2");
    }
    catch(IllegalStateException  e1){
        System.out.println("2");
    }
    catch(NullPointerException  e1){
        System.out.println("2");
    }
    catch(AssertionError e1){
        System.out.println("2");
    }
    catch(ExceptionInInitializerError  e1){
        System.out.println("2");
    }
    catch(StackOverflowError  e1){
        System.out.println("2");
    }
    catch(NoClassDefFoundError  e1){
        System.out.println("2");
    }
    catch(ArrayStoreException e1){
        System.out.println("2");
    }
    catch(IllegalMonitorStateException e1){
        System.out.println("2");
    }
    catch(IndexOutOfBoundsException e1){
        System.out.println("2");
    }
    catch(NegativeArraySizeException e1){
        System.out.println("2");
    }
    catch(SecurityException e1){
        System.out.println("2");
    }
    catch(UnsupportedOperationException e1){
        System.out.println("2");
    }
    catch(Exception e1){
        System.out.println("2");
    }
}

}

现在,所有未经检查的异常都在到达 catch(Exception e) 之前得到处理。那么,除了这些之外是否还有未经检查的异常,因为没有生成编译错误?还是别的什么?

【问题讨论】:

  • 因为除了ArithmeticException之外还有未勾选的Exceptions。
  • 你不需要为 try 块中的逻辑设置第二个 catch 块。仅当它抛出 ArithmeticException 以外的情况时,控制才转到第二个 catch 块(异常)。因此,您仍然可以编写第二个 catch 块,这完全没有问题。
  • @MarkoTopolnik 如果我在最后一个块之前添加所有未经检查的异常怎么办?会一样吗?
  • 我添加了一些代码。请往上看。
  • 不会,因为你不知道运行时可能会抛出哪些未经检查的异常。编译时和运行时的类路径完全不同,异常类也可能是动态生成的。

标签: java exception exception-handling


【解决方案1】:

在 Java 中,catch 块按照它们在源文件中出现的顺序被触发。

因此,如果更一般的Exception 先出现,如果ArithmeticException 被抛出,并且第二个catch 块无法访问,它也会触发。

另一方面,如果更具体的ArithmeticException 的catch 块首先出现,那么Exception 的catch 块不会变得不可访问,因为Exception 的子类没有被第一个区块。

【讨论】:

    【解决方案2】:

    更具体的异常 - ArithmeticException - 应该首先出现,因为它允许您以不同于一般处理 Exception 的方式处理它。

    如果您将异常处理程序或Exception 放在首位,则使ArithmeticException 的处理程序成为死代码,因为它永远无法到达 - 任何ArithmeticException 都将被Exception 的处理程序捕获。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 2021-09-19
      • 2021-02-13
      • 2021-07-18
      • 2021-12-28
      相关资源
      最近更新 更多