我有这样的方法:
public void getSomething(){ ... }
我想抛出一个Exception内getSomething()。编译器不允许我这样做,因为不允许Exception将我的方法扔在那里。但是我需要抛出一个的子类来Exception进行测试 (我不能抛出UncheckedException)。显然这是一个hack,但我需要进行测试。我尝试过EasyMock,但它也不允许我这样做。任何想法如何做到这一点?
Exception
getSomething()
谢谢,肖恩·阮
方法1:
Alexey Ragozin的这篇文章介绍了如何使用泛型技巧引发未声明的检查异常。从该帖子:
public class AnyThrow { public static void throwUnchecked(Throwable e) { AnyThrow.<RuntimeException>throwAny(e); } @SuppressWarnings("unchecked") private static <E extends Throwable> void throwAny(Throwable e) throws E { throw (E)e; } }
诀窍依靠throwUnchecked“说谎”到编译器的类型E是RuntimeException与它的调用throwAny。由于throwAny被声明为throws E,编译器认为特定的调用可能会抛出RuntimeException。当然,可以通过throwAny任意声明E并盲目地对其进行强制转换而使技巧成为可能,从而允许调用者确定其参数在强制编码时的强制转换为可怕的设计。在运行时,将E被擦除并且没有任何意义。
throwUnchecked
E
RuntimeException
throwAny
throws E
如您所述,做这样的事情是一个巨大的漏洞,您应该很好地记录它的使用。
方法2:
您也sun.misc.Unsafe可以为此使用。首先,您必须实现一个使用反射来返回该类实例的方法:
sun.misc.Unsafe
private static Unsafe getUnsafe() { try { Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeField.setAccessible(true); return (Unsafe)theUnsafeField.get(null); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }
这是必需的,因为调用Unsafe.getUnsafe()通常会引发SecurityException。一旦有了实例,Unsafe就可以使用其强大的功能:
Unsafe.getUnsafe()
SecurityException
Unsafe
Unsafe unsafe = getUnsafe(); unsafe.throwException(new Exception());
值得信赖的是在帖子[http://codingdict.com/questions/4269)上的答案。我以为是出于完整性的考虑而提到了它,但是最好使用上面的技巧而不是允许您的代码进入。Unsafe
方法3:
在有关使用的链接答案的注释中Unsafe,@bestsss指出了不建议使用的方法简单得多的技巧Thread.stop(Throwable):
Thread.stop(Throwable)
Thread.currentThread().stop(new Exception());
在这种情况下,您将@SuppressWarnings("deprecation")非常猛烈地使用并再次进行记录。同样,我比较喜欢它的(相对)清洁度。
@SuppressWarnings("deprecation")