有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java抓住可丢弃的东西是一种不好的做法吗?

Throwable是一种坏习惯吗

例如,类似这样的事情:

try {
    // Some code
} catch(Throwable e) {
    // handle the exception
}

这是一种不好的做法,还是我们应该尽可能具体


共 (6) 个答案

  1. # 1 楼答案

    这是个坏主意。事实上,即使抓到Exception通常也是个坏主意。让我们考虑一个例子:

    try {
        inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
    } catch(Throwable e) {
        inputNumber = 10; //Default, user did not enter valid number
    }
    

    现在,假设getUserInput()阻塞了一段时间,另一个线程以最糟糕的方式停止了您的线程(它调用thread.stop())。catch块将捕获ThreadDeath错误。这太糟糕了。捕获该异常后,代码的行为基本上是未定义的

    捕捉异常也会出现类似的问题。可能getUserInput()失败是因为在尝试记录结果时发生了中断异常、权限被拒绝的异常,或者其他各种失败。你不知道出了什么问题,因为正因为如此,你也不知道如何解决问题

    你有三个更好的选择:

    1--准确捕获您知道如何处理的异常:

    try {
        inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
    } catch(ParseException e) {
        inputNumber = 10; //Default, user did not enter valid number
    }
    

    2--重新显示遇到的任何不知道如何处理的异常:

    try {
        doSomethingMysterious();
    } catch(Exception e) {
        log.error("Oh man, something bad and mysterious happened",e);
        throw e;
    }
    

    3--使用finally block,这样你就不必记得重复:

     Resources r = null;
     try {
          r = allocateSomeResources();
          doSomething(r);
     } finally {
         if(r!=null) cleanUpResources(r);
     }
    
  2. # 2 楼答案

    如果你绝对不能从一个方法中产生一个异常泡泡,那么这是一个不错的做法

    如果你真的不能处理异常,这是一种糟糕的做法。向方法签名中添加“throws”比捕获并重新抛出更好,或者更糟糕的是,将其包装在RuntimeException中并重新抛出

  3. # 3 楼答案

    你需要尽可能具体。否则,不可预见的错误可能会以这种方式悄悄溜走

    除此之外,^{}还包括^{},这就是usually no point of return。你不想捕捉/处理它,你希望你的程序立即死亡,这样你就可以正确地修复它

  4. # 4 楼答案

    如果您使用的库会热情地抛出错误,那么捕获Throwable有时是必要的,否则您的库可能会杀死您的应用程序

    然而,在这种情况下,最好只指定库抛出的特定错误,而不是所有可丢弃的错误

  5. # 5 楼答案

    直接从错误类的javadoc(建议不要捕捉这些错误):

     * An <code>Error</code> is a subclass of <code>Throwable</code> 
     * that indicates serious problems that a reasonable application 
     * should not try to catch. Most such errors are abnormal conditions. 
     * The <code>ThreadDeath</code> error, though a "normal" condition,
     * is also a subclass of <code>Error</code> because most applications
     * should not try to catch it. 
    
     * A method is not required to declare in its <code>throws</code> 
     * clause any subclasses of <code>Error</code> that might be thrown 
     * during the execution of the method but not caught, since these 
     * errors are abnormal conditions that should never occur. 
     *
     * @author  Frank Yellin
     * @version %I%, %G%
     * @see     java.lang.ThreadDeath
     * @since   JDK1.0
    
  6. # 6 楼答案

    还要注意,当你捕捉Throwable时,你也可以捕捉InterruptedException,这需要特殊处理。有关更多详细信息,请参见Dealing with InterruptedException

    如果您只想捕捉未检查的异常,您也可以考虑这个模式

    try {
       ...
    } catch (RuntimeException exception) {
      //do something
    } catch (Error error) {
      //do something
    }
    

    这样,当您修改代码并添加一个方法调用时,编译器会提醒您这一点,然后您可以决定如何处理这种情况