gpt4 book ai didi

java - 当您的方法签名不允许抛出异常时如何抛出异常?

转载 作者:IT老高 更新时间:2023-10-28 21:00:12 24 4
gpt4 key购买 nike

我有这样的方法:

public void getSomething(){
...
}

我想在 getSomething() 中抛出一个 Exception。编译器不允许我这样做,因为我的方法不允许在其中抛出 Exception。但是我需要为我的测试 抛出一个 Exception 的子类(我不能抛出 Unchecked Exception)。这显然是一个 hack,但我需要它来进行测试。我尝试了 EasyMock,但它也不允许我这样做。任何想法如何做到这一点?

谢谢,肖恩·阮

最佳答案

方法一:

This post by 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 向编译器“撒谎”类型 ERuntimeException 并调用 throwAny。由于 throwAny 被声明为 throws E,编译器认为特定的调用只能抛出 RuntimeException。当然,这个技巧是通过 throwAny 任意声明 E 并盲目地转换为它来实现的,允许调用者决定它的参数被转换为什么 - 理智编码时的糟糕设计.在运行时,Eerased并且没有任何意义。

正如你所说,做这样的事情是一个巨大的黑客,你应该很好地记录它的使用。


方法二:

您也可以为此使用 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());

归功于 this answer在帖子 https://stackoverflow.com/questions/5574241/interesting-uses-of-sun-misc-unsafe .我想我会为了完整性而提到这一点,但最好只使用上面的技巧而不是允许 Unsafe 进入你的代码。


方法三:

在有关使用 Unsafe 的链接答案的评论中,@bestsss points out使用已弃用的方法 Thread.stop(Throwable) 的更简单的技巧:

Thread.currentThread().stop(new Exception());

在这种情况下,您将使用 @SuppressWarnings("deprecation") 并再次非常激烈地记录。同样,我更喜欢第一个技巧,因为它的(相对)清洁度。

关于java - 当您的方法签名不允许抛出异常时如何抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11942946/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com