Java - 抛出异常与捕获和重新抛出异常之间的区别

Mic*_*878 5 java exception try-catch throws

我很困惑抓住和重新抛出一个例外而不仅仅是把它放在首位.

例如

private void testMethod() throws Exception
{
    //some bad code here
} 
Run Code Online (Sandbox Code Playgroud)

与:

private void testMethod() throws Exception
{
    try
    {
        //some bad code here
    }
    catch (Exception e)
    {
        throw e;
    }
} //end testMethod()
Run Code Online (Sandbox Code Playgroud)

这是为了保留错误消息的堆栈跟踪吗?我尝试设置一个示例,但两者之间没有看到任何不同的输出.

谢谢您的帮助.

mer*_*ike 6

两个代码示例之间的行为没有区别.(特别是,在创建异常时记录堆栈跟踪,而不是在抛出异常时记录,因此重新抛出的异常仍将具有原始堆栈跟踪).通常,人们因此使用更简单的习语.

这并不是说重新抛出没有它的用​​途.例如,如果您想处理除FooBarExceptions之外的所有异常,您可以编写:

try {
    // bad code 
} catch (FooBarException e) {
    throw e;
} catch (Exception e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

或者,如果处理异常的决定比简单地检查它的类型更复杂,那么你可以简单地捕获它,如果事实证明你无法处理它,则重新抛出:

for (int attempts = 0; attemps < 6; attempts++) {
    try {
        return crankyMethod();
    } catch (Exception e) {
        if (fatal(e)) {
            throw e;
        } else {
            // try again
            continue;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,当人们说重新抛出时,有些人意味着抛出不同的异常,如下例所示:

for (int i = 0; i < array.length; i++) {
    try {
        process(array[i]);
    } catch (Exception e) {
        throw new RuntimeException("Could not process element at index " + i, e);
    }
}
Run Code Online (Sandbox Code Playgroud)

此模式的优点是使用可能相关的其他信息来装饰原始异常(在上面的示例中:无法处理哪些数据).请注意,原始异常将传递给新构造函数的构造函数,因此其堆栈跟踪不会丢失.


Pab*_*ruz 0

没有区别。除非你想在重新抛出它之前对它做一些事情(例外)。