0

从 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 块与众不同(除了捕获异常和它是一个块的事实)?

谢谢你的帮助。

4

3 回答 3

7

catch子句中的语法并非完全偏离 OOP 标准。

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

catch (IllegalArgumentException | OutOfMemoryError e)

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

相反,在您的示例中,

public int test(int | double d)

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

所以我认为在这种try...catch情况下你可以通过继承静态类型变量;在您的示例中,这是不可能的,这就是禁止它的原因。

于 2013-10-19T19:49:38.213 回答
2
try{
        ...
    }
    catch(FileNotFoundException | IOException e){
        e.printStackTrace();
    }

您也不能这样做,因为FileNotFoundException它的子类是IOException:multi-catch 语句中的替代项不能通过子类化来关联

于 2013-10-19T19:40:31.930 回答
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);
} 
于 2013-10-19T19:50:42.310 回答