实用工具类重新抛出一个可以取消选中? [英] Utility class that re-throws a throwable as unchecked?

查看:163
本文介绍了实用工具类重新抛出一个可以取消选中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在捕获单元测试包装器方法中的所有可抛物线,以便重置外部系统中的一些数据。我想重新抛出原来的异常,当这样做完成后,我正在使用这段代码:

  if (t instanceof RuntimeException){
throw(RuntimeException)t;
} else if(t instanceof Error){
throw(Error)t;
} else {
throw new RuntimeException(t);
}

但是,有没有现有的实用程序调用已经这样做了?



(由于AssertionErrors是错误,我正在捕捉到throwable。)



编辑:说实话,我真的不想为了包装异常,所以任何允许我抛出任何可抛出(包括已检查的异常)而不声明throws的技巧是可以接受的。

解决方案

p>是的,有一种方法来编写一个方法,避免包装你检查的异常。对于这种用例,这是一个完美的搭配,虽然你一定要非常小心,因为它可以很容易地混淆未开始的。这是:

  public class UncheckedThrower {
public static< R> R trhow(Throwable t){
return UncheckedThrower。< RuntimeException,R> trhow0(t);
}
@SuppressWarnings(unchecked)
private static< E extends Throwable,R> R trhow0(Throwable t)抛出E {
throw(E)t;
}
}

您将使用它作为

  catch(Throwable t){trhow(t); } 

与适当的静态导入。如Joachim Sauer所言,在某些情况下,它有助于说服编译器, trhow 总是抛出异常。这简单地可以通过简单地缩减返回值来实现:

  catch(Throwable t){throw(RuntimeException)trhow(t); } 

并且可以避免略过 trhow

  public static RuntimeException trhow(Throwable t){
return UncheckedThrower。< RuntimeException,的RuntimeException> trhow0(T);
}

这可以用作



(pre> catch(Throwable t){throw trhow(t); }

(Khm ...现在我实际上重命名它,但是,你看到点。)



出于教育目的,很高兴看到字节码级别发生了什么。 javap -private -c UncheckedThrower 中的相关代码段:

  private static java.lang.Object trhow0(java.lang.Throwable)throws java.lang.Throwable; 
代码:
0:aload_0
1:athrow

显然,没有投票检查说明。该方法甚至合法声明抛出任何 Throwable ,这是 E 的擦除。


I am catching all throwables in a unit test wrapper method in order to reset some data in an external system. I want to re-throw the original exception when this is done and I am using this piece of code to do it:

if (t instanceof RuntimeException) {
    throw (RuntimeException) t;
} else if (t instanceof Error) {
    throw (Error) t;
} else {
    throw new RuntimeException(t);
}

However, is there any existing utility call that does this already?

(I am catching throwables because AssertionErrors are Errors.)

Edit: To be honest, I don't really want to wrap the exception, so any trick that would allow me to throw any throwable (including checked exceptions) without declaring throws is acceptable.

解决方案

Yes, there is a way to write a method that will avoid wrapping your checked exceptions. For this use case it is a perfect match, although you should definitely be very careful with it, since it can easily confuse the uninitiated. Here it is:

public class UncheckedThrower {
  public static <R> R trhow(Throwable t) {
    return UncheckedThrower.<RuntimeException, R>trhow0(t);
  }
  @SuppressWarnings("unchecked")
  private static <E extends Throwable, R> R trhow0(Throwable t) throws E { 
    throw (E)t; 
  }
}

and you'd use it as

catch (Throwable t) { trhow(t); }

with the appropriate static import. As commented by Joachim Sauer, in certain cases it helps convince the compiler that trhow always throws an exception. This is trivially achievable by simply downcasting the return value:

catch (Throwable t) { throw (RuntimeException) trhow(t); }

and the downcast can be avoided with a slight change to trhow:

public static RuntimeException trhow(Throwable t) {
  return UncheckedThrower.<RuntimeException, RuntimeException>trhow0(t);
}

This you can use as

catch (Throwable t) { throw trhow(t); }

(Khm... now I'd actually rename it, but well, you see the point.)

For educational purposes it is nice to see what's going on at the bytecode level. The relevant snippet from javap -private -c UncheckedThrower:

private static java.lang.Object trhow0(java.lang.Throwable) throws java.lang.Throwable;
  Code:
   0: aload_0
   1: athrow

Obviously, no cast check instructions present. The method even legitimately declares to throw any Throwable, which is the erasure of E.

这篇关于实用工具类重新抛出一个可以取消选中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆