(后期编辑:这个问题将有望被淘汰时的Java 7自带因为的,"最终重投"功能,这似乎将被添加.)
很多时候,我发现自己处于这样的情况:
do some initialization
try {
do some work
} catch any exception {
undo initialization
rethrow exception
}
在C#中你可以这样做:
InitializeStuff();
try
{
DoSomeWork();
}
catch
{
UndoInitialize();
throw;
}
Run Code Online (Sandbox Code Playgroud)
对于Java来说,没有很好的替代,并且由于改进的异常处理的提议是从Java 7中删除的,所以看起来好几年才能得到类似的东西.因此,我决定自己动手:
(编辑: 半年后,最后的重新抛出回来了,或者看起来如此.)
public final class Rethrow {
private Rethrow() { throw new AssertionError("uninstantiable"); }
/** Rethrows t if it is an unchecked exception. */
public static void unchecked(Throwable t) {
if (t instanceof Error)
throw (Error) t;
if (t instanceof RuntimeException)
throw (RuntimeException) t;
}
/** Rethrows t if it is an unchecked exception or an instance of E. */
public static <E extends Exception> void instanceOrUnchecked(
Class<E> exceptionClass, Throwable t) throws E, Error,
RuntimeException {
Rethrow.unchecked(t);
if (exceptionClass.isInstance(t))
throw exceptionClass.cast(t);
}
}
Run Code Online (Sandbox Code Playgroud)
典型用法:
public void doStuff() throws SomeException {
initializeStuff();
try {
doSomeWork();
} catch (Throwable t) {
undoInitialize();
Rethrow.instanceOrUnchecked(SomeException.class, t);
// We shouldn't get past the above line as only unchecked or
// SomeException exceptions are thrown in the try block, but
// we don't want to risk swallowing an error, so:
throw new SomeException("Unexpected exception", t);
}
private void doSomeWork() throws SomeException { ... }
}
Run Code Online (Sandbox Code Playgroud)
这有点罗嗦,抓住Throwable通常不赞成,我真的很高兴使用反射只是为了重新抛出异常,我总是觉得有点不安写"这不会发生"的评论,但在实践中它运作良好(或似乎,至少).我想知道的是:
Throwable可能是由于某种严重的事情导致我的undoInitialize意志失败,但那没关系.)
ExceptionUtils但那还有其他的事情.编辑:
finally不是我正在寻找的机器人.抛出异常时我只对做事情感兴趣.Throwable是一个很大的禁忌,但我认为这是两害取其轻这里相比具有三个catch子句(对Error,RuntimeException和SomeException,分别)具有相同的代码.try只要我重新启动了一些内容,块中抛出的任何异常都会继续通过调用堆栈冒出来.有两种方法可以解决这个问题.如果您不需要知道异常是什么,首先是我的偏好.
boolean okay = false;
try {
// do some work which might throw an exception
okay = true;
} finally {
if (!okay) // do some clean up.
}
Run Code Online (Sandbox Code Playgroud)
在某些情况下,您可以在没有额外变量的情况下执行相同操作,具体取决于try块的功能.
第二个选择是黑客,但也有效.
try {
// do some work which might throw an exception
} catch (Throwable t) {
// do something with t.
Thread.currentThread().stop(t);
}
Run Code Online (Sandbox Code Playgroud)
stop(Throwable t)方法不会停止线程,而是导致线程以未经检查的方式抛出异常.
您可以使用Unsafe.throwException()进行一些摆弄,并且有一种方法可以使用Generics执行此操作,我已经忘记了.
| 归档时间: |
|
| 查看次数: |
1631 次 |
| 最近记录: |