为什么我可以在catch块上捕获多个异常,但不在方法中放入多个参数?

时间:2013-10-19 19:34:09

标签: java parameter-passing

从Java 7开始,可以使用以下代码:

    try{
        ...
    }
    catch(FileNotFoundException | SomeOtherException e){
        e.printStackTrace();
    }

但是在方法中模拟语法不是:

    public int test(int |double d){
        ...
    }

而必须这样做

    public int test(int d){
        ...
    }
    public int test(double d){
        ...
    }

或者这个:

    public class Foo<E>{
        ...
        public int test(E something){
            ...
        }
    }

为什么我不能在catch块中的方法中做更简单的事情?是什么让catch块不同,(除了捕获异常和它是一个块的事实)?

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

catch子句中的语法与OOP标准完全不同。

e变量的编译器类型是您声明的所有异常的公共超类。所以如果你声明这样的话,

catch (IllegalArgumentException | OutOfMemoryError e)

然后e的实际类型为Throwable,这确实有道理。因此,在catch块内部,您不能调用特定于两个异常中任何一个的方法,而只能调用Throwable类中存在的方法。

在您的示例中,

public int test(int | double d)

d的编译类型是什么? Java是静态类型的,所以这个声明没有任何意义。

所以我认为在try...catch情况下你可以通过继承静态地输入变量;在你的例子中,这是不可能的,这就是它被禁止的原因。

答案 1 :(得分:2)

try{
        ...
    }
    catch(FileNotFoundException | IOException e){
        e.printStackTrace();
    }

您也不能这样做,因为FileNotFoundExceptionIOException的子类:多重捕获语句中的替代方法无法通过子类化来关联

答案 2 :(得分:1)

当您捕获多个异常时,变量e具有最接近的公共超类的类型,通常为Exception。您无法使用int|double执行此操作,因为它们没有共同的超类(它们是基元)。

你可以用方法做类似的事情:

// Instead of 
public void test(IOException | NullPointerException e) {...
// Just write
public void test(Exception e) { ...

这当然会接受所有例外情况。为了防止这种情况,你可以写:

public void test(IOException e) {test2(e);}
public void test(NullPointerException e) {test2(e);}
private void test2(Exception e) { ...

你可能会争辩说使用|运算符作为简写是有用的,但实际上你很少在现实世界中这样做。所以没有希望实现这一点。

另一方面,您经常在捕获异常时执行此操作。在java中引入multi-catch之前,你经常会看到这样的东西:

} catch(FileNotFoundException e){
    handleException(e);
} catch(IllegalArgumentException e){
    handleException(e);
} catch(SomeOtherException e){
    handleException(e);
}