从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块不同,(除了捕获异常和它是一个块的事实)?
感谢您的帮助。
答案 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();
}
您也不能这样做,因为FileNotFoundException
是IOException
的子类:多重捕获语句中的替代方法无法通过子类化来关联
答案 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);
}