无法在Multi catch中解析异常类

时间:2016-06-01 13:40:11

标签: java exception-handling multi-catch

我正在使用multicatch(Java 7及更高版本)创建自定义异常类。这是我创建的类。 请参考以下代码:

public class CustomException extends Exception{

public CustomException() {
    System.out.println("Default Constructor");
}
public CustomException(ArithmeticException e, int num){
    System.out.println("Divison by ZERO! is attempted!!! Not defined.");
}
public CustomException(ArrayIndexOutOfBoundsException e, int num){
    System.out.println("Array Overflow!!!");
}
public CustomException(Exception e, int num){
    System.out.println("Error");
}

以上课程由以下课程扩展。

import java.util.Scanner;

public class ImplementCustomException extends CustomException {

public static void main(String[] args) throws CustomException {
    int num = 0;
    System.out.println("Enter a number: ");
    try(Scanner in = new Scanner(System.in);){

        num = in.nextInt();
        int a = 35/num;

        int c[] = { 1 };
        c[42] = 99;
    }
    catch(ArithmeticException|ArrayIndexOutOfBoundsException e){

        throw new CustomException(e, num);
    }
}
}

每次我试图运行它时,它都会调用相同的构造函数,即带有“Exception”的构造函数。 为什么会这样?

但是,如果我用以下代码替换multi-catch语法。它按预期工作。

catch(ArithmeticException ex){
        CustomException e = new CustomException(ex, num);
        throw e;
}
catch(ArrayIndexOutOfBoundsException ex){
        CustomException e = new CustomException(ex, num);
        throw e;
}

请协助我进行可能的更改,以便使用多次捕获并使其抛出所需的异常。

2 个答案:

答案 0 :(得分:4)

除了ArithmeticException之外,ArrayIndexOutOfBoundsExceptionException没有共同的父母。在这一块

catch(ArithmeticException|ArrayIndexOutOfBoundsException e){
    throw new CustomException(e, num);
}

e获取静态类型,这是 Exception RuntimeException。有了这个,就会调用CustomException(Exception e, int num)

如果你将它们分开,e有一个更专用的类型。

答案 1 :(得分:3)

行为在JLS Sec 14.20中通过这个不太突出的句子定义:

  

声明类型的异常参数,表示其类型为与替代D1 | D2 | ... | Dn的联合,为lub(D1, D2, ..., Dn)

lub表示“最小上限”,在JLS Sec 4.10.4中定义:

  

一组引用类型的最小上限或“lub”是一个共享超类型,它比任何其他共享超类型更具体(也就是说,没有其他共享超类型是最小上限的子类型)。

在您的情况下,lubArithmeticException的{​​{1}}为ArrayIndexOutOfBoundsException,因此将RuntimeException作为参数类型的重载是最具体的方法可以被称为。

请记住,编译器决定要调用的重载:它不是在运行时决定的。