尝试捕获异常帮助器

时间:2020-06-21 02:32:22

标签: java spring performance try-catch try-catch-finally

我已经创建了一个帮助程序,该帮助程序在另一个函数中使用 Exception 参数返回错误消息。(这是一个示例)

void func(int n){ 
    try { 
        // this will throw ArithmeticException if n is 0 
        int x = 10 / n; 
        int y[] = new int[n]; 
        y[x] = 10; 

        // this will throw ArrayIndexOutOfBoundsException 
        // if the value of x surpasses 
        // the highest index of this array 
        System.out.println("No exception arose"); 
    } 
    catch (Exception e) { 
        System.out.println(getErrorType(e)); 
    } 
} 

String getErrorType(Exception e){
    String errorMessage = "";
    if (e instanceof ArithmeticException) 
        errorMessage = "ArithmeticException, Can't divide by 0";
    if (e instanceof ArrayIndexOutOfBoundsException) 
        errorMessage = "ArrayIndexOutOfBoundsException, This index doesn't exist in this array";
    else
        errorMessage = "error";
    return errorMessage;
}

如您所见,我正在使用 instanceof 来获取Exception类型,并且我还可以向String函数添加更多信息,例如错误消息。另外,我可以在此帮助程序中包含许多错误类型。 我的问题是,

  • 在Java中使用好吗?
  • 以这种方式使用它有很多不便之处?
  • 还有另一种方法可以实现我想做的事情?
  • 它如何影响性能?

我已经知道在try catch块中很好的用途是使用特定的Exceptions来添加具有特定Exception的catch级别。但是我想使其通用化。

4 个答案:

答案 0 :(得分:0)

通常,您希望在try / catch子句中指定期望发生的异常,这样,当其他人浏览您的代码时,他们将知道如果他们需要处理它们,将会想到哪些异常。

实际上,您也可以通过以下操作将catch子句组合为一个子句:

try { 
    // this will throw ArithmeticException if n is 0 
    int x = 10 / n; 
    int y[] = new int[n]; 
    y[x] = 10; 

    // this will throw ArrayIndexOutOfBoundsException 
    // if the value of x surpasses 
    // the highest index of this array 
    System.out.println("No exception arose"); 
} 
catch (ArithmeticException | ArrayIndexOutOfBoundsException | SomeOtherException e) { 
    e.printStackTrace(); 
} 

答案 1 :(得分:0)

似乎有很多额外的工作,而且我看不到将所有异常处理代码放在大型函数中的好处。 Java的最佳实践是始终保持代码模块化,并尽可能地利用该语言。

如果只是您想要的详细信息,则使用自定义消息重新抛出异常会更巧妙。这是一个简单的示例:

int divide (int a, int b) {
    try {
        return a / b;
    } catch (ArithmeticException e) {
        throw new ArithmeticException("Divide by 0", e);
    }
}

请记住,您要以不同的方式处理异常,因为您不希望您的应用程序因可修复的小事情而终止-这不是一个好的设计。如果您的应用遇到了可以从中恢复的问题,例如来自用户的错误输入,则可以捕获异常并停止崩溃。使用通用异常将阻止您执行此操作,因为您将不知道引发了什么异常。您可以在getErrorType函数中进行处理,但最终可能会遇到类似这样的情况:

String getErrorType(Exception e){
    String errorMessage = "";
    if (e instanceof ArithmeticException) 
        errorMessage = "ArithmeticException, Can't divide by 0";
        warnUserToChangeValue();
    if (e instanceof IllegalArgumentException) 
        errorMessage = "Bad Argument";
        warnUserToChangeValue();    
    if (e instanceof ArrayIndexOutOfBoundsException) 
        errorMessage = "ArrayIndexOutOfBoundsException, This index doesn't exist in this array";
    else
        errorMessage = "error";
    return errorMessage;
}

这真的很难看。我建议保持简单,并根据需要进行捕获:

catch (ArithmeticException e |  IllegalArgumentException e) 
{
    // The user probably entered a bad value, no reason to terminate, just tell them
    warnUserToChangeValue(); 
}

答案 2 :(得分:0)

捕获 Exception 通常是一个不好的做法,因为它还会吞噬无关的错误,例如NullPointerException,IllegalStateException,IllegalArgumentException和其他运行时异常,这些错误都是BUGS,实际上应该继续传播。

因此使用:

FF, FE

捕获IllegalArgumentException确实是一种糟糕的做法,除了在错误处理的最顶层。在这种情况下,您所能做的就是将其报告到某个地方(例如日志)。

这是一个错误。

该规则的一个例外是,当您拥有诸如Thread之类的东西时,因为它非常关键,因此永不中断。

在这种情况下,捕获Throwable更为有效。

答案 3 :(得分:0)

TL; DR

丢弃整个try / catch块,并使用最顶层的方法告诉用户您无法执行他命令您执行的任务。

概念

看起来您对如何处理特殊情况有着(广泛的)误解,即“异常很糟糕!我必须尽早发现它们!”错了异常可以完美地告诉呼叫者我的失败:“我无法完成工作。您可以决定是否可以不这样做,以其他方式重试,或者只是向呼叫者发送信号”。

您的func()有一些工作要做(无论“合同”可能是什么)。从方法中抛出异常是为了表明该方法未完全完成其工作。

在您的情况下,func()调用者没有机会发现该方法无法执行任何操作(因此很可能无法履行其合同)。因此,您的呼叫者会开心地继续前进,而不知道他的算法的关键步骤失败了,从而产生跟进错误,甚至更糟:数据废话。

因此,不捕获异常绝对是更好的选择,异常会波及到您的呼叫者,这样他就可以知道失败的原因,并可以决定是否即使在func()失败之后也可以明智地继续。

在大多数情况下,该决定显示为“如果我的算法中的任何事情失败,整个事情失败了,我立即想中止其所有计算”。如果您什么都没抓住,那就是免费从异常中获取的东西。

您的捕获条款

与Java Runtime与该异常关联的自动文本格式相比,您尝试呈现一种用户友好的消息来更好地描述问题。

乍一看,这似乎是合理的,但是...

如果此func()是代码深处使用的帮助程序,那么坐在机器前的最终用户将发现您的措辞比Java文本更有帮助。仅当您实现了一个桌面计算器,其中用户明确希望将两个数相除时,有关零除的错误文本对用户才有帮助。在典型情况下,他无法将零除与他希望从您的程序中得到的任何内容(例如,信用利息计算)相关联。

回答您的问题

    如上所述,您的一般方法有一些缺点。我怀疑您是否可以仅从异常对象创建独立于发生错误的代码的,对用户敏感的错误消息。在Java中使用“ instanceof”几乎总是一个坏主意。
  • 是的,这很不方便。您写很多行而没有宝贵的好处。
  • 如果您真的想保留与异常类型相关的文本,请对不同的异常类使用多个catch子句。
  • 我认为这不会带来明显的性能差异。如果错误处理的性能很重要,则您的软件必须解决一个非常奇怪的领域。