当前位置:  开发笔记 > 编程语言 > 正文

我的安全重新安全有多安全?

如何解决《我的安全重新安全有多安全?》经验,为你挑选了1个好方法。

(后期编辑:这个问题将有望被淘汰时的Java 7自带因为的,"最终重投"功能,这似乎将被添加.)


很多时候,我发现自己处于这样的情况:

    do some initialization
    try {
        do some work 
    } catch any exception {
        undo initialization
        rethrow exception
    }

在C#中你可以这样做:

InitializeStuff();
try
{
    DoSomeWork();
}
catch 
{
    UndoInitialize();
    throw;
}

对于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  void instanceOrUnchecked(
            Class 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通常不赞成,我真的很高兴使用反射只是为了重新抛出异常,我总是觉得有点不安写"这不会发生"的评论,但在实践中它运作良好(或似乎,至少).我想知道的是:

    我的重新抛出辅助方法有任何缺陷吗?我错过了一些角落案件?(我知道这Throwable可能是由于某种严重的事情导致我的undoInitialize意志失败,但那没关系.)

    有人已经发明了这个吗?我看了Commons Lang的,ExceptionUtils但那还有其他的事情.


编辑:

finally不是我正在寻找的机器人.抛出异常时我只对做事情感兴趣.

是的,我知道捕Throwable是一个很大的禁忌,但我认为这是两害取其轻这里相比具有三个catch子句(对Error,RuntimeExceptionSomeException,分别)具有相同的代码.

请注意,我并没有试图压制任何错误 - 我的想法是,try只要我重新启动了一些内容,块中抛出的任何异常都会继续通过调用堆栈冒出来.

Peter Lawrey.. 5

有两种方法可以解决这个问题.如果您不需要知道异常是什么,首先是我的偏好.

boolean okay = false;
try {
  // do some work which might throw an exception
  okay = true;
} finally {
  if (!okay) // do some clean up.
}

在某些情况下,您可以在没有额外变量的情况下执行相同操作,具体取决于try块的功能.

第二个选择是黑客,但也有效.

try {
    // do some work which might throw an exception
} catch (Throwable t) {
    // do something with t.
    Thread.currentThread().stop(t);
}

stop(Throwable t)方法不会停止线程,而是导致线程以未经检查的方式抛出异常.

您可以使用Unsafe.throwException()进行一些摆弄,并且有一种方法可以使用Generics执行此操作,我已经忘记了.



1> Peter Lawrey..:

有两种方法可以解决这个问题.如果您不需要知道异常是什么,首先是我的偏好.

boolean okay = false;
try {
  // do some work which might throw an exception
  okay = true;
} finally {
  if (!okay) // do some clean up.
}

在某些情况下,您可以在没有额外变量的情况下执行相同操作,具体取决于try块的功能.

第二个选择是黑客,但也有效.

try {
    // do some work which might throw an exception
} catch (Throwable t) {
    // do something with t.
    Thread.currentThread().stop(t);
}

stop(Throwable t)方法不会停止线程,而是导致线程以未经检查的方式抛出异常.

您可以使用Unsafe.throwException()进行一些摆弄,并且有一种方法可以使用Generics执行此操作,我已经忘记了.

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有