在主要功能或调用层次结构中较低的致命异常之后退出

时间:2018-07-31 23:59:23

标签: java exception-handling

如果我有一个程序调用了引发异常的方法,该方法必须在抛出特定异常时终止,我是否应该对其进行设计,以便将该异常传递回main以便可以安全地返回,或者应该处理函数中的异常并调用System.exit(-1)

以下是我在函数中处理它的意思的示例:

public class MyClass{
     public static void main (String[] args){
        myFunction(args);
     }
     public static void myFunction(String[] args){
          try{
              if(args.length == 0) 
                   throw Exception("Invalid Input");
          }catch(Exception e){
              System.out.println(e);
              System.exit(-1);
          }
     }
 }

这是我的意思的一个例子:

public class MyClass{
     public static void main (String[] args){
        try{
             myFunction(args);
        }catch(Exception e){ 
             System.out.println(e);
        }
     }
     public static void myFunction(String[] args) throws Exception{
         if(args.length == 0)
              throw Exception("Invalid Input");
     }
 }

在这种情况下应使用哪种方式?

4 个答案:

答案 0 :(得分:1)

这对我来说是一个非常棘手的问题,我现在只想分享一些想法。

您需要注意两个主要因素:

  1. 致命吗?您可以防止它破坏/关闭程序吗?
  2. 您能做些例外吗?记录一些有用的信息?通过某些方法还原它?

1号

如果它是致命的,那么您最好尝试将程序exit捕获在适当的层中,以确保它正常运行,也许是在抛出异常或更高异常的地方(取决于2号); < / p>

2号

如果您想跟踪一些有用的信息以进行调试甚至恢复(如果可能)。

然后,是否在特定位置捕获和处理它取决于您的项目/系统。

以正常情况为例:

如果需要在调用层中跟踪信息,则应在较低层中捕获异常并抛出异常,以使调用层/较高层具有该异常:

  1. 要么记录一些有用的调试信息
  2. 或通过其他方法将其恢复(例如,您已引入了策略性模式,也许您应该尝试其他策略来替换当前策略来处理同一工作);

另一个字

不要尝试将exception引入您的项目/系统逻辑,exception应被视为处理意外问题的异常。

很抱歉添加此内容,希望对您有所帮助。

答案 1 :(得分:0)

来自this post

  

当您使用知道该怎么做的方法时,应该捕获异常。

如果引发异常的方法知道如何处理错误,则应该处理该错误。否则,如果该方法不知道如何处理该异常,则应将其抛出。

在您的问题中,由于您希望在异常发生时退出程序,因此将异常返回给main方法可能很有意义。

This post也有一些很好的信息。

答案 2 :(得分:0)

几乎没有理由致电System.exit。也许在某些灾难性的情况下,您想立即停止JVM,很难想象会是什么。因此,我想说,如果没有一些非常具体的要求,切勿调用System.exit

try-catch方法中设置main块,捕获Throwable并将其记录下来。这样可以最大程度地减少程序其他地方的异常处理,并鼓励采用一种快速失败的编程方式,以免异常被吞噬和丢失。

或者,也许您有一个从Shell脚本运行的小型Java程序。您可以让main方法抛出Exception并让Shell脚本调用者将stderr重定向到文件。但是使用真实的记录器可以更好地控制滚动和清除等操作。

如果您担心会引发一些无法记录的错误(可能是我们内存不足,并且无法在没有引起另一个内存不足错误的情况下进行记录),则除了将记录添加到调用方之外,为了预防起见,让Java程序自己进行日志记录。

答案 3 :(得分:0)

可以以某种方式回答这个问题,从本质上讲,它不是主要基于观点的问题。

首先,考虑相关的问题“ when should you throw an exception”吗? correct answer的意思是“当且仅当备选方案是无法建立发布条件或保持不变”。这提醒我们要考虑方法发布条件。您提供了一个用于解析命令行参数的方法的示例。应该具有“命令行参数有效”的后置条件。因此,如果命令行参数无效,则该规则告诉我们该方法应引发异常,而不必终止。

第二,考虑为什么根本没有例外。有没有它们的编程语言(特别是C)。替代方法是使用状态代码。异常的优点之一是,它们将对问题(在引发异常的地方)的检测与确定在出现问题(在其中捕获异常)的情况下的处理方式分开。它们为上级调用方法提供了“向上推策略”的方法。因此,如果出现问题(例如您的示例中的无效命令行参数),程序应该终止吗?这是一个政策问题,因此属于较高级别的方法,而不属于较低级别的方法。同样的论点适用于程序的所有级别:没有任何方法可以证明终止程序,实施最严厉的策略是合理的,因为它可以通过引发异常将策略向上推。不能向上推策略的唯一方法是main方法,因为它没有调用者向上推。这表明只有main方法才应导致程序终止。请注意,JVM是以这种方式运行的:即使是根本无法处理的虚拟机错误,也应该导致程序终止,导致抛出VirtualMachineError,而不是直接终止程序。