我有这样的方法:
public void getSomething(){
...
}
我想抛出一个Exception
内getSomething()
编译器将不允许我这样做,因为我的方法不允许Exception
在那里被抛出。 但我需要抛出的子类Exception
为我的测试(我不能把未经检查的Exception
)。 这显然是一个黑客,但我需要为我的测试。 我尝试了EasyMock,但它不允许我这样做,要么。 任何想法如何做到这一点?
谢谢,肖恩·阮
我有这样的方法:
public void getSomething(){
...
}
我想抛出一个Exception
内getSomething()
编译器将不允许我这样做,因为我的方法不允许Exception
在那里被抛出。 但我需要抛出的子类Exception
为我的测试(我不能把未经检查的Exception
)。 这显然是一个黑客,但我需要为我的测试。 我尝试了EasyMock,但它不允许我这样做,要么。 任何想法如何做到这一点?
谢谢,肖恩·阮
方法1:
本帖由阿列克谢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
被删除 ,并没有任何意义。
正如你提到的,在做这样的事情是一个巨大的黑客,你应该记录它的使用非常好。
方法2:
您还可以使用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 unsafe = getUnsafe();
unsafe.throwException(new Exception());
幸得此答案的帖子https://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe 。 我想我会提到这一点的完整性,但它可能只是为了更好地使用上述伎俩,而不是允许Unsafe
到你的代码。
方法3:
在有关使用链接的答案的评论Unsafe
, @bestsss指出使用过时的方法更简单的伎俩Thread.stop(Throwable)
:
Thread.currentThread().stop(new Exception());
在这种情况下,你可以使用@SuppressWarnings("deprecation")
并再次记录非常激烈。 同样,我更喜欢它的(相对)清洁第一招。
Java有两种异常,检查,未经检查的。 您必须声明检查异常,但你不必申报unchecked异常。
RuntimeException
是基本未经检查的异常,所以你可以把那未声明的。
public void getSomething(){
throw new RuntimeException("I don't have to be declared in the method header!");
}
作为一个侧面说明,你可能不想抛出RuntimeException的原料,但它继承更具体的您的需要的东西。 RuntimeException的任何子类,将取消选中为好。
我不知道你想干什么。 你可以只抛出一个未经检查的异常的方法内,然后测试使用JUnit像下面的示例所示。
public void getSomething() {
throw new RuntimeException();
}
JUnit 4测试实施例:
@Test
public void testGetSomething() {
try {
getSomething();
fail("Expecting RuntimeException!");
} catch (Exception e) {
Logger.getLogger("test").info("Exception was caught: " + e.getClass());
}
}