在Java中,如果捕获并重试了一般异常,外部方法是否仍然能够捕获特定异常?

在Java中,如果捕获并重试了一般异常,外部方法是否仍然能够捕获特定异常?,java,exception,exception-handling,try-catch,rethrow,Java,Exception,Exception Handling,Try Catch,Rethrow,在Java中,如果捕获并重试了一般异常,外部方法是否仍然能够捕获特定异常 换句话说,我可以这样做: try { try { //... } catch (Exception e) { //... throw e; } } catch (SpecificException e) { //... } 重新抛出异常不会改变它的任何内容(它仍然是最初抛出的同一个对象)。重新抛出异常不会改变它的任何内容(它仍然是最初

在Java中,如果捕获并重试了一般异常,外部方法是否仍然能够捕获特定异常

换句话说,我可以这样做:


try {
    try {
         //...
    } catch (Exception e) {
         //...
        throw e;
    }
} catch (SpecificException e) {
     //...
}

重新抛出异常不会改变它的任何内容(它仍然是最初抛出的同一个对象)。

重新抛出异常不会改变它的任何内容(它仍然是最初抛出的同一个对象)。

Eclipse将内部捕获中的“抛出e”标记为未处理的异常,但它确实捕获了异常,因为当我运行这个时,它会打印“它工作了!”。谢谢@jtahlborn。不幸的是,这意味着在某些地方仍然需要一个不必要的try/catch块


public class Tester {

    public static void main(String[] args) {
        try {
            try {
                throw new SpecificException("Test!");
            } catch (Exception e) {
                throw e;
            }
        } catch (SpecificException e) {
            System.out.println("It worked!");
        }
    }

}
Eclipse将内部捕获中的“throw e”标记为未处理的异常,但它确实捕获了异常,因为当我运行它时,它会打印“it worked!”。谢谢@jtahlborn。不幸的是,这意味着在某些地方仍然需要一个不必要的try/catch块


public class Tester {

    public static void main(String[] args) {
        try {
            try {
                throw new SpecificException("Test!");
            } catch (Exception e) {
                throw e;
            }
        } catch (SpecificException e) {
            System.out.println("It worked!");
        }
    }

}

虽然jtahlborn的答案是正确的,但还有一点值得赞赏:编译器将看到您正在抛出泛型类型的异常(即使在运行时它只能是特定类的异常),并将强制您在方法头中声明泛型异常

private void test() throws FileNotFoundException {
    try {
        throw new FileNotFoundException("Es una exception");
    } catch (IOException e) {
        throw e; <-- Error because the method only throws
                       FileNotFoundException, not IOException
    }
}

虽然jtahlborn的答案是正确的,但还有一点值得赞赏:编译器将看到您正在抛出泛型类型的异常(即使在运行时它只能是特定类的异常),并将强制您在方法头中声明泛型异常

private void test() throws FileNotFoundException {
    try {
        throw new FileNotFoundException("Es una exception");
    } catch (IOException e) {
        throw e; <-- Error because the method only throws
                       FileNotFoundException, not IOException
    }
}

但是,如果您捕获了多个异常,那么您就不知道将其转换到哪个异常。如果您捕获了多个异常,那么您应该实际捕获它们。这就是编译器不允许这样做的原因。然后,要么用
instanceof
检查类型并执行一个类属转换,要么坚持在method
throws
子句中声明泛型异常(在父方法中,您仍然可以检查哪一个是原始异常-但您必须覆盖“泛型”异常,因为编译器无法确定它是否不需要)。不管怎么说,您的操作太复杂了,要么调用方法必须对异常进行相同的处理(然后坚持使用泛型方法),要么不进行处理(在
throws
中声明不同的特定异常),但是,如果捕获多个异常,那么你就不知道该把它转换到哪一个。如果你捕获了多个异常,那么你就应该实际捕获它们。这就是编译器不允许这样做的原因。然后,要么用
instanceof
检查类型并执行一个类属转换,要么坚持在method
throws
子句中声明泛型异常(在父方法中,您仍然可以检查哪一个是原始异常-但您必须覆盖“泛型”异常,因为编译器无法确定它是否不需要)。不管怎么说,您的操作太复杂了,要么调用方法必须对异常进行相同的处理(然后坚持使用泛型方法),要么不进行处理(在
抛出
中声明不同的特定异常),这是多么不幸
catch(异常e)
将捕获从类
Exception
(应该是全部)派生的任何异常。然后你抛出它,然后只处理一些特定的异常。java不应该允许这样!如果您希望某个异常能够实际终止应用程序,那么您应该使用运行时异常,因为不必捕获这些异常。根据运行时类型捕获异常,但编译器必须仅决定其警告和错误的静态信息。当然,在您的情况下,我们仍然可以区分catch
Exception
只能捕获
specifiception
,但对于任何真正的问题,这都是一个困难的问题。但无论如何,你不应该抓到比你必须抓到的更多的东西。这怎么会是不幸的呢
catch(异常e)
将捕获从类
Exception
(应该是全部)派生的任何异常。然后你抛出它,然后只处理一些特定的异常。java不应该允许这样!如果您希望某个异常能够实际终止应用程序,那么您应该使用运行时异常,因为不必捕获这些异常。根据运行时类型捕获异常,但编译器必须仅决定其警告和错误的静态信息。当然,在您的情况下,我们仍然可以区分catch
Exception
只能捕获
specifiception
,但对于任何真正的问题,这都是一个困难的问题。但无论如何,你不应该抓得太多。