java - throw e 和 throw new Exception(e) 有什么区别?

标签 java exception try-catch throw

考虑:

try  {
    // Some code here
} catch (IOException e) {
    throw e;
} catch (Exception e) {
    throw e;
}

throw ethrow new Exception(e) 有什么区别?

try  {
   // Some code here
} catch (IOException e) {
   throw new IOException(e);
} catch (Exception e) {
   throw new Exception(e);
}

最佳答案

如果您不需要调整异常类型,则重新抛出(进一步抛出)同一个实例而不做任何更改:

catch (IOException e) {
    throw e;
}

如果确实需要调整异常类型,则e(作为原因)包装到所需类型的新异常中.

catch (IOException e) {
    throw new IllegalArgumentException(e);
}

我认为所有其他情况都是代码异味。您的第二个片段就是一个的例子。


以下是可能出现的问题的答案。

Why would I want to rethrow an exception?

你可以放手。但是,如果发生这种情况,您将无法在此级别上做任何事情。

当我们在方法中捕获异常时,我们仍然在该方法中并且可以访问其范围(例如局部变量及其状态)。在我们重新抛出异常之前,我们可以做任何我们需要做的事情(例如记录一条消息,将它发送到某个地方,制作当前状态的快照)。

Why would I want to adjust an exception?

根据经验,

Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.

Effective Java - 2nd Edition - Item 61: Throw exceptions appropriate to the abstraction

换句话说,在某些时候,一个不起眼的 IOException 应该被转换成一个明显的 MySpecificBusinessRuleException

我称之为“调整异常类型”,聪明人称之为异常翻译(特别是异常链接) .


为了清楚起见,让我们举一些愚蠢的例子。

class StupidExample1 {
    public static void main(String[] args) throws IOException {
        try {
            throw new IOException();
        } catch (IOException e) {
            throw new IOException(new IOException(e));
        }
    }
}

导致类似的详细堆栈跟踪

Exception in thread "main" java.io.IOException: java.io.IOException: java.io.IOException
    at StupidExample1.main(XXX.java:XX)
Caused by: java.io.IOException: java.io.IOException
    ... 1 more
Caused by: java.io.IOException
    at StupidExample1.main(XXX.java:XX)

可以(并且应该)有效地减少到

Exception in thread "main" java.io.IOException
    at StupidExample1.main(XXX.java:XX)

另一个:

class StupidExample2 {
    public static void main(String[] args) {
        takeString(new String(new String("myString")));
    }

    static void takeString(String s) { }
}

很明显 new String(new String("myString"))"myString" 的罗嗦版本,应该重构为后者。

关于java - throw e 和 throw new Exception(e) 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54982437/

相关文章:

java - 迭代时修改整数集和字符串集

Java:关闭我的应用程序但出现异常

java - 使用 try-catch 验证输入

c# - C# "finally" block 是否总是执行?

java - 即使将依赖项添加到 pom.xml 也会发生 NoClassDefFoundError

node.js - 什么是我的node.js try/catch最简洁的选择?

java - 我怎样才能让一行代码运行一次?

java - 有没有什么好的解释java语言的库?

python - Tornado AsyncHTTPClient.fetch 异常

asp.net - 如何在ASP.NET中处理WCF异常