当前位置: 首页 > 面试题库 >

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

东方琪
2023-03-14
问题内容

我有这样的方法:

public void getSomething(){
...
}

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

谢谢,肖恩·阮


问题答案:

方法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“说谎”到编译器的类型ERuntimeException与它的调用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());

值得信赖的是在帖子[http://codingdict.com/questions/4269)上的答案。我以为是出于完整性的考虑而提到了它,但是最好使用上面的技巧而不是允许您的代码进入。Unsafe

方法3:

在有关使用的链接答案的注释中Unsafe,@bestsss指出了不建议使用的方法简单得多的技巧Thread.stop(Throwable)

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

在这种情况下,您将@SuppressWarnings("deprecation")非常猛烈地使用并再次进行记录。同样,我比较喜欢它的(相对)清洁度。



 类似资料:
  • 在你可以捕获异常之前,一些代码必须抛出一个异常。任何代码都可能会抛出异常:您的代码,来自其他人编写的包(例如Java平台附带的包)或Java运行时环境的代码。无论是什么引发的异常,它总是通过 throw 语句抛出。 您可能已经注意到,Java平台提供了许多异常类。所有类都是Throwable类的后代,并且都允许程序区分在程序执行期间可能发生的各种类型的异常。 您还可以创建自己的异常类来表示在您编写

  • 抛出异常的行为是否可能抛出不同的异常? 为了抛出异常,必须(可选地)分配新对象,并调用其构造函数(隐式调用fillinstacktrace)。在某些情况下,听起来像addSupressed也被称为。那么如果没有足够的内存会发生什么呢?JVM是否需要预分配内置异常?例如,(1/0)会抛出OutOfMemoryError而不是ArithmeticException吗? 此外,构造函数是一个方法调用,因

  • 我知道JVM有一个异常表,它映射在给定字节码索引中可以抛出的可能异常。我还读到athrow字节码抛出了堆栈顶部存在的引用类型的exception。我的问题更多地涉及像irem这样的指令如何“抛出”异常。 JVM是否会在每次指令执行后检查堆栈的顶部,以检查是否存在异常?如果你能洞察到这件事的话,你会很感激的。

  • 问题内容: 考虑以下代码: 无需添加方法签名即可编译该代码。(它与同样表现到位,太)。 我理解为什么 可以 安全地运行它,因为实际上不能将其引发在块中,因此不能引发已检查的异常。我有兴趣知道在何处指定此行为。 并非永远都不会达到目标:以下代码也会编译: 但是,如果抛出一个检查的异常,它不会像我期望的那样编译: 在JLS Sec 11.2.2中 ,它说: 一,其抛出的表达式语句(§14.18)具有静

  • 我在其中一个POJO中使用javax.validation.constraints.NotNull,如下所示: 然后,即使我为两个字段都使用 null 值制作 Abc 的对象,它也不会引发任何异常。知道为什么吗? 例如。 不会抛出任何异常。

  • 我想知道为什么java编译器允许在方法声明中抛出,而方法永远不会抛出异常。因为“throws”是处理异常的一种方式(告诉调用方处理它)。 因为有两种处理异常的方法(抛出和try/catch)。在try/catch中,它不允许捕获try块中未抛出的异常,但它允许在不抛出异常的方法中抛出。