【问题标题】:Exception handling when overridden method does not throw any exception被覆盖的方法不抛出任何异常时的异常处理
【发布时间】:2023-03-27 16:15:01
【问题描述】:

简写形式:当被覆盖的方法不抛出异常时,你如何抛出异常(或进行良好、干净的异常处理;或者至少是肮脏地强制停止执行)?

上下文:我们有一个专有软件的许可证,该软件可以使用 Java“宏”实现自动化。用户定义的宏必须是这种形式:

public class MyMacro extends SoftwareMacro {
    public void execute() {
        // user code goes here
    }
}

即扩展SoftwareMacro 的类,并且有一个名为execute 的方法覆盖基类'execute。这个覆盖 execute 的内容是在“播放”宏时得到......好吧......执行。

但是被覆盖的execute 方法显然不会抛出任何异常。

execute() in com.mycompany.mypackage.MyMacro cannot implement execute() in 
somesoftware.base.SoftwareMacro
overridden method does not throw java.lang.Exception

也许这很幼稚,但在开发过程中,我通常喜欢让适当的异常类型冒泡到顶部并强制执行停止,这样我就可以看到它们并继续调试。这显然不是这里的选择。

我应该求助于投掷RuntimeException 吗? (因为RuntimeException不需要指定)感觉有点草率,和基类方法矛盾的“精神上的违背”。

附:不,我不能更改被覆盖的 execute 方法的源代码。

【问题讨论】:

  • 干净的方法是拥有一个集中的“异常”处理程序,该处理程序将从覆盖方法内部检测“引发”异常并停止应用程序执行。务实的方法是抛出 RuntimeException。
  • @DaveHowes - 是的,你误读了,对不起。 Java 要求覆盖方法的异常规范是被覆盖方法的适当子集;空集当然是真子集。您不需要抛出与超类相同的异常。

标签: java exception-handling


【解决方案1】:

看起来意图是每个SoftwareMacro 都进行自己的错误处理。如果需要,在整个execute() 方法周围使用一个大的try,但不要让任何异常逃逸。在你的执行方法中做任何你需要做的清理工作,如果他们提供了这样做的方法,可能会为用户打印一条错误消息。

您应该检查他们提供的所有 API——也许您应该使用错误报告工具。

【讨论】:

    【解决方案2】:

    这完全取决于“宏播放器”在遇到运行时异常时会做什么,以及您希望发生什么。

    如果它根本不处理它,但你不在乎,抛出一个 RuntimeException。

    如果处理得当,则抛出 RuntimeException。

    如果它没有正确处理它们,并且您不希望它惨遭失败,那么捕获可能在您的执行方法中发生的异常,并按照您认为最好的方式处理它们:显示错误对话框,输出错误信息,在日志中记录一些错误...

    【讨论】:

      【解决方案3】:

      “应该”意味着有一个正确的答案,而 IMO 并不能满足您的需求。

      如果系统可以容忍运行时异常,并且满足您的需求,为什么不呢?

      不是你有选择,因为你不能抛出一个检查异常。

      (检查异常对我来说似乎是一个失败的实验,尽管我理解其动机。)

      【讨论】:

      • 嗯,我正在努力养成良好的习惯和良好的做法,这就是“应该”所暗示的。我正在寻找比满足眼前需求更有远见的东西。
      • @Jean-FrançoisCorbett 好习惯是……好,但只有当满足你想要做的事情的需要时。显然,作者认为所有错误处理都应该在宏内完成,并且可能是合适的——这取决于上下文。然而,由于没有提供任何特定于框架的异常签名,他们已经把你锁在里面了。考虑一下 Ernest 所说的——是否有报告错误的框架机制?此外,即使系统实际上没有停止,您仍然可以记录异常以供检查。
      【解决方案4】:

      只要execute 代码不吸收异常,它仍然会在遇到异常时抛出它。如果抛出的异常类型是RuntimeExceptionRuntimeException 的子类,则它们不需要显式声明,主要是因为编译器不强制执行它们的声明,因为(顾名思义)它们只发生在运行时,并且不能必然在编译时预测。

      但是,如果您说无法修改的 execute 方法吸收了异常,并且不会通过日志条目、返回值或某种 RuntimeException 指示该异常我觉得你运气不好。

      我同意 Ernest 的观点,其意图似乎是 execute 方法自己处理所有异常。

      注意:当涉及到它们抛出的异常时,被覆盖的方法签名不需要完全匹配 - 只需名称、返回类型以及变量的列表和类型。

      【讨论】:

      • 嗯,不,不完全匹配,但是覆盖方法仅限于抛出被覆盖方法指定异常的子集(而不是超集)。
      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2015-11-15
      • 1970-01-01
      • 2018-11-06
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多