【问题标题】:Java: How to throw a custom Runtime Exception without using a throw statement?Java:如何在不使用 throw 语句的情况下抛出自定义运行时异常?
【发布时间】:2016-05-28 07:13:25
【问题描述】:

比如说,我想在我当前的包中的任何地方防止除以 3。通常的程序是创建一个 Exception 子类:

class NoDivbyThreeException extends RuntimeException {
    public NoDivbyThreeException (String msg) {
        super(msg);
    }
}

然后扔到需要的地方:

class CustomExceptionDemo {
    public static void main(String[] args) {
        int numr = 5;
        int denr = 3;
        try {
            if (denr==3) throw new NoDivbyThreeException("Div by 3 not allowed");
            else System.out.println("Result: " + numr/denr);
        }
        catch (NoDivbyThreeException e) {
            System.out.println(e);
        }
     }
}

但我想要的是 JVM 应该防止在这个包中的任何地方除以 3,而无需我在 main() 中明确声明 throw 语句。换句话说,JVM通过在遇到这种情况时自动抛出异常来防止除以零的方式,我希望我的程序在包内遇到除以3的情况时也这样做。

这可能吗?如果不是,请详细说明原因。这将有助于理清我的概念。

【问题讨论】:

  • 您是说希望它的行为就像您尝试除以 0 时一样?
  • 不可能。简短说明:stackoverflow.com/questions/21269461/…
  • 当然,这很简单。只需将源代码编辑到 JVM 本身,然后构建您自己的版本。然后你可以让它做任何你想做的事情。 --- 我说“容易”吗?是的,也许不是。
  • Scala 的类似问题,使用 implicit 方法甚至不可能 - stackoverflow.com/questions/4443783/…
  • @Gendarme 是的,但只在当前包中说,而不是在它之外

标签: java exception runtimeexception


【解决方案1】:

我认为这是不可能的。

您希望5 / 3 抛出异常,对吗?和5 / 0一样吗?根据this answer,“在 Unix 环境中,除零是通过 SIGFPE 发出信号的,JVM 将安装一个信号处理程序,该处理程序会捕获 SIGFPE 并反过来引发 ArithmeticException。”

换句话说,5 / 0 引起的错误不是从 JVM 开始的,而是从 Java 之外的 CPU 或内核开始的。不能让 CPU 或内核在除以 3 时抛出异常,也不能覆盖 Java 中的除法行为。

另见

【讨论】:

    【解决方案2】:

    如果不明确抛出 Exception,就无法抛出它。除了一些内部的Exceptions,如除以0,由JVM处理。这些包括NullPointerException,如果不是由显式的 throw 语句抛出,除以 0 和一些其他错误。但这些异常实际上是通过从底层平台接收错误而创建的。例如。在除以 0 的情况下,错误已经由 CPU 产生。

    因此,除非您的代码以某种方式在底层平台中产生错误,否则您必须自己创建错误。其他任何事情都需要 JVM 高度可变,由于不一致的行为,这没有多大意义,这是不可取的,并且会导致极端的安全风险。举例说明为什么不希望使 JVM 可变:
    考虑你的例子:

    我们可以有三个选项来处理这个问题(不存在,AFAIK):

    • 更改编译器中的代码,如果发生任何被三除(可能),则抛出异常。缺点:膨胀代码
    • 改变 JVM 的行为:更不可取。考虑一个引发除以 3 异常的库。现在您想在代码中使用该库。但是您期望正常的算术行为并在除以 3 时得到一些奇怪的错误。
    • 向库中添加一个标头来描述 JVM 的预期行为。与第一个选项相比,只有负载从编译和内存移动到运行时和启动/运行时编译。

    【讨论】:

    • 谢谢,我明白了。您是否碰巧知道任何好的资源来阅读 JVM 如何引发内部异常或任何类似的事情?
    • @Vignatus 你的意思是像被0除的异常吗?一个很好的起点是JVM的规范
    【解决方案3】:

    为此,您必须修改 java.lang.ArithmeticException ,如果他们知道您想将 ArithmeticException 除以 3 ,我相信当局不会让您这样做 :)。

    【讨论】:

    • 我实际上试图修改它,但后来我看到 java.lang.ArithmeticException 只有将参数传递给其超类 (RuntimeException) 的构造函数,而后者又将其再次传递给超类,依此类推。所以源文件中没有描述何时抛出异常的代码
    • 我们在这里讨论的是 JDK 的变化。我认为创建“除以 3 异常”是不合理的,但这里是有关如何为开源 JDK 做出贡献的指南的链接:openjdk.java.net/contribute
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 2018-11-07
    相关资源
    最近更新 更多