Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 捕获可丢弃项并处理特定异常_Java_Exception_Exception Handling - Fatal编程技术网

Java 捕获可丢弃项并处理特定异常

Java 捕获可丢弃项并处理特定异常,java,exception,exception-handling,Java,Exception,Exception Handling,好吧,我知道抓一次性的不是个好主意: try { // Some code } catch(Throwable e) { // Not cool! // handle the exception } 但最近我正在阅读一段开源代码,我看到了这段有趣的代码(至少对我来说是这样): try { // Some Code } catch (Throwable ex){ response = han

好吧,我知道抓一次性的不是个好主意:

    try {
         // Some code
    } catch(Throwable e) { // Not cool!
        // handle the exception
    }
但最近我正在阅读一段开源代码,我看到了这段有趣的代码(至少对我来说是这样):

    try {
        // Some Code
    } catch (Throwable ex){
        response = handleException(ex, resource);
    }

    private handleException(Throwable t, String resource) {
        if (t instanceof SQLEXception) {
               // Some code
        } else if (t instanceof IllegalArgumentException) {
               //some code
        } //so on and so forth
    }

这看起来没那么糟吧?这种方法有什么问题?

有各种各样的原因说明你不应该抓住一次性的东西。首先,
Throwable
包括
Error
s-如果出现其中一个,应用程序通常不会有太多功能。此外,抛弃也减少了你发现发生了什么的机会。你得到的只是“发生了一些不好的事情”——这可能是一场灾难,也可能只是一个麻烦

另一个aproach更好,但当然我仍然不会捕获Throwable,但如果可能的话,尝试捕获更具体的异常。否则你会抓住一切,然后试着找出发生了什么坏事。你的例子可以写成

try {
    ...
} catch (SQLEXception ex){
    response = ... ;
} catch (IllegalArgumentException ex){
    response = ...;
}

…这将减少(…instanceof…块)的
数量(这只是因为作者第一次决定在一个大桶中捕获所有内容才需要)。它实际上是
抛出可丢弃的
,那么你当然没有太多选择

你说得对,抓捕可丢弃的
不是一个好主意。但是,您在问题中提出的代码并不是以一种邪恶的方式捕捉到可丢弃的
,我们稍后再讨论。目前,您在问题中提出的代码有几个优点:

1。可读性

如果仔细查看代码,您会注意到,即使catch块正在捕获一个
可丢弃的
handleException
方法正在检查抛出的异常类型,并可能根据异常类型采取不同的操作

您问题中的代码等同于:

try {
    doSomething();
} catch (SQLEXception ex){
    response = handleException(resource);
} catch(IllegalArgumentException ex) {
    response = handleException(resource);
} catch(Throwable ex) {
    response = handleException(resource);
}
即使您只需要捕获10+个异常,此代码也很容易占用大量代码行,而且多捕获结构不会使代码变得更干净。您在问题中呈现的代码只是将
catch
委托给另一个方法,以使实际的方法更具可读性

2。可重用性

该方法的代码可以很容易地修改并放置在实用程序类中,并在整个应用程序中访问,以处理
异常
s和
错误
s。您甚至可以将该方法提取为两个
private
方法;一个处理
异常
的,一个处理
错误
的,并且具有
handleException
方法,该方法采用
可丢弃
进一步将调用委托给这些方法

3。可维护性

如果您决定要更改应用程序中记录
SQLException
s的方式,则必须在单个位置进行此更改,而不是访问引发
SQLException
的每个类中的每个方法

那么,捕获可丢弃的
是个坏主意吗

您在问题中呈现的代码实际上与单独捕获
Throwable
不同。下面的代码是一个很大的禁忌:

try {
   doSomething();
} catch(Throwable e) {
    //log, rethrow or take some action
}
您应该在
catch
链中尽可能远的地方捕获
Throwable
Exception


最后但并非最不重要的一点是,请记住,您在问题中提供的代码是框架的代码,并且框架仍然可以从某些错误中恢复。请参阅以获得更好的解释。

因为懒惰而捕获可丢弃的东西是个坏主意。

在引入
try multi-catch
之前,这尤其诱人

try {
   ...
} catch (SomeException e) {
   //do something
} catch (OtherException e) {
   //do the same thing
} ...
重复catch块既单调又冗长,因此有些人决定只捕获
异常
可丢弃的
,然后处理它。这是应该避免的,因为:

  • 这使得你很难理解你想做什么
  • 你可能会遇到很多你无法处理的事情
  • 如果您完全吞下catch block中的
    可丢弃物品
    ,则应受到额外惩罚。(我们都见过这样做的代码…:))
  • 但是在绝对必要的时候捕捉可丢弃的
    是可以的。

    什么时候有必要?很少。在框架风格的代码中有各种场景(动态加载外部类是最明显的场景),在独立应用程序中,典型的示例是在退出之前尝试显示/记录某种错误消息。(请记住,尝试可能会失败,因此您不希望将任何关键内容放在那里。)


    根据经验,如果您对异常/错误无能为力,您就不应该捕获它。

    首先,捕获Throwable会使您的应用程序相当不持久。您应该尽可能明确地捕获异常,以便在异常情况下实现良好的可跟踪性

    让我们看一看handleException方法(…),看看这种方法会出现的一些问题:

    • 您捕获Throwable,但只处理异常,如果抛出类型为Error的OutOfMemoryError,会发生什么情况?-我看到坏事发生了
    • 关于使用instanceof进行良好的面向对象编程,它打破了开闭原则,使代码更改(例如添加新的异常)变得非常混乱

    在我看来,catch块正是为尝试在handleException(…)中覆盖的功能而设计的,所以请使用它们。

    Java7解决了一点繁琐的问题,即使用类似的处理多次捕获类似的异常。你绝对不应该做这个人在这里做的事。只要根据需要捕获适当的异常,它可能看起来很难看,但这就是
    public static void main(String args[]) {
        try {
            new Test().test();
        } catch (Throwable t) {
            t.printStackTrace(System.err);
        }
    }
    
              try{
    
                  //do something that could throw an exception
    
                 }catch (ConnectException e) {
                    //do something related to connection
    
    
                } catch (InvalidAttributeValueException e) {
                    // do anything related to invalid attribute exception
    
                } catch (NullPointerException e) {
    
                    // do something if a null if obtained
                }
    
                catch (Exception e) {
                // any other exception that is not handled can be catch here, handle it here
    
                }
                finally{
              //perform the final operatin like closing the connections etc.
                 }