在C#中,我可以使用throw;
语句重新抛出异常并保留堆栈跟踪:
try
{
...
}
catch (Exception e)
{
if (e is FooException)
throw;
}
Java中有类似这样的东西吗(不会丢失原始堆栈跟踪)?
catch (WhateverException e) {
throw e;
}
显然,周围的方法必须通过签名等方式允许此操作。否则,您捕获的异常将被简单地重新抛出,并保留原始的堆栈跟踪。
catch(Exception e) { throw e; }
这段代码,异常将无法被处理。如果你写了 catch(InterruptedException ie) { throw ie; }
则可以处理这个异常。通常情况下,不要使用 catch(Exception e)
这样的代码,因为我们不像玩 Pokémon 一样抓住所有的异常! - corsiKa你还可以将异常包装在另一个异常中,并通过将异常作为原因参数传递给Throwable来保留原始堆栈跟踪:
try
{
...
}
catch (Exception e)
{
throw new YourOwnException(e);
}
throw new YourOwnException("在尝试...时发生错误", e);
。 - JulienYourOwnException
的情况下,此代码才能正常工作。请参阅RuntimeException
上的4个公共构造函数,这些构造函数调用了super
。 - Captain ManI would prefer:
try
{
...
}
catch (FooException fe){
throw fe;
}
catch (Exception e)
{
// Note: don't catch all exceptions like this unless you know what you
// are doing.
...
}
在Java中几乎是相同的:
try
{
...
}
catch (Exception e)
{
if (e instanceof FooException)
throw e;
}
e
的代码,那么这段代码才有意义。否则,使用instanceof
就不太合适了。您可以添加省略号或注释来说明这一点。 - istepaniuk在Java中,您只需要抛出捕获到的异常,因此使用throw e
而不是仅使用throw
。Java会维护堆栈跟踪。
如果您将捕获的异常包装到另一个异常中(以提供更多信息),或者仅重新抛出捕获的异常,则保留堆栈跟踪。
try{
...
}catch (FooException e){
throw new BarException("一些有用的信息", e);
}
像这样的东西
。try
{
...
}
catch (FooException e)
{
throw e;
}
catch (Exception e)
{
...
}
我之前遇到了类似的情况,我的代码可能会抛出多种不同的异常,而我只想重新抛出它们。上面描述的解决方案对我没有用,因为Eclipse告诉我throw e;
会导致一个未处理的异常,所以我就这样做:
try
{
...
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {
throw new RuntimeException(e.getClass().getName() + ": " + e.getMessage() + "\n" + e.getStackTrace().toString());
}
e
的信息。最好使用throw new RuntimeException("一些有用的信息", e)
将原始异常打包。在字符串中,提供一些有用的信息,这些信息在e
中缺失,例如您的方法的一些重要参数、上下文信息或者任何有助于调试的内容。 - Florian H.
Throwable
时不会修改它们。要更新堆栈跟踪,必须调用fillInStackTrace()
方法。方便的是,这个方法在Throwable
的构造函数中被调用。 - Robertthrow e;
会丢失堆栈跟踪信息。但在Java中不会。 - Tim Goodman