(后期编辑:这个问题将有望被淘汰时的Java 7自带因为"final rethrow" feature其中seems like it will be added的)我的安全再次安全有多安全?
很多时候,我发现自己在寻找这样的情况:
do some initialization try { do some work } catch any exception { undo initialization rethrow exception }
在C#中,你可以做这样的:
InitializeStuff();
try
{
DoSomeWork();
}
catch
{
UndoInitialize();
throw;
}
对于Java而言,没有好的替代品,并且自the proposal for improved exception handling was cut from Java 7以来,看起来它最多只需要几年时间,直到我们得到类似的东西。因此,我决定推出自己的:
(编辑:半年后,final rethrow is back,或者看起来是这样)
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);
}
}
典型用途:
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 { ... }
}
这是一个有点啰嗦,Throwable
通常是皱眉,我不是很喜欢用反射来重新抛出一个异常,而且我总是感到有点不自在写“这不会发生”的评论,但实际上它的工作原理是w埃尔(或者似乎至少)。我想知道的是:
- 我的rethrow帮助器方法有任何缺陷吗?我错过了一些角落案件? (我知道
Throwable
可能是由一些如此严重的东西造成的,以至于我的undoInitialize
会失败,但没关系。)- 有人已经发明了这个吗?我看着Commons Lang的
ExceptionUtils
,但那是做其他事情的。
- 有人已经发明了这个吗?我看着Commons Lang的
编辑:
finally
是不是我要找的机器人。我只有在抛出异常时才有兴趣做些什么。- 是的,我知道追赶
Throwable
是一大禁忌,但我认为这是两害取其轻这里相比具有三个catch子句(对于Error
,分别RuntimeException
和SomeException
)具有相同的代码。 - 请注意,我并没有试图压制任何错误 - 想法是
try
块中抛出的任何异常会在我重新执行一些操作时立即通过调用堆栈。
你有抓住Throwable的好理由。不要让它让你失望。这很像使用GOTO,“除非必须,否则不要使用它。” –