异常处理问题

Upu*_*ara 32 java exception-handling

我有一个关于异常处理的问题.请考虑遵循Java代码段.

        try{
            //code
        }catch(SubSubException subsubex){
            //code
        }catch(SubException subex){
            //code
        }catch(Exception ex){
            //code
        }
Run Code Online (Sandbox Code Playgroud)

我知道这是处理异常的推荐方法.但是我可以通过使用以下代码片段来实现相同的功能.

        try{
            //code
        }catch ( Exception ex){
            if( ex instanceof SubException){              
                //code
            }else if(ex instanceof SubSubException){
                //code
            }else{
                //code
            }
        }
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我第二种方法的缺点吗?

Woo*_*Moo 111

第二种方法不太可读.此外,即使你的"聪明"技巧是使用instanceof关键字,口袋妖怪异常处理也永远不会成为可能.无论如何,我并不是在开玩笑或嘲笑你,但最好是为人类编写代码来阅读和维护,而不是为计算机编写代码.

  • 从来没有听说它被称为口袋妖怪异常处理 - 我喜欢它. (44认同)
  • 我们应该将"口袋妖怪异常处理"变成官方的反模式! (25认同)
  • 我只能希望它能抓住:) (7认同)
  • 我想知道"口袋妖怪异常处理"来自哪里......:o)我也喜欢它! (3认同)
  • +1提及"最好编写供人类阅读和维护的代码".如此真实. (3认同)
  • @Woot4Moo - 理解起来可能有点深奥。时间会证明一切。 (2认同)
  • @Stephen口袋妖怪实际上只比Java年轻一岁:( (2认同)
  • TDWTF对Pokemon异常处理有很好的说明:http://forums.thedailywtf.com/forums/t/8499.aspx (2认同)

pol*_*nts 40

是的,MadMurf指出了最重要的区别:在编译时进行可达性检查.标准习惯用法会捕获这样的东西并正确地防止它编译:

    try {
    } catch (IndexOutOfBoundsException iooe) {
    } catch (ArrayIndexOutOfBoundsException aiooe) {
    }
Run Code Online (Sandbox Code Playgroud)

在原始问题中提出的if/instanceof analog会编译(这不是你想要的,因为它是错误的).

标准习惯用法在编译时捕获错误的原因在JLS 14.21无法到达的语句中给出.

  • 如果满足以下两个条件,则可以访问catch块C:
    • [...]
    • try语句中没有先前的catch块,因此C的参数类型与A参数类型的子类相同.

为了进一步说明这一点,以下编译:

    try {
    } catch (Exception e) {
        if (e instanceof Exception) {
        } else if (e instanceof Exception) {
        }
    }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这种"口袋妖怪捕捉"成语更难维护,因为它绕过了标准习语中强制执行的一些编译时可达性检查.

为了更清楚地说明这一点,无论你是否故意这样做,你实际上都重新安排了你在原始问题中检查异常的顺序,这个事实很容易被其他人遗漏.如果SubSubException是SubException的子类,则永远不会评估第二个if条件,并且它的主体实际上是无法访问的代码.

if/instanceof方法非常容易出错.

  • 其他人已经提出了有效的观点,但这是最好的答案.作为程序员,我们永远不应该做编译器可以为我们做的工作. (10认同)

ult*_*ohn 23

嗯,为什么你甚至要做第二种方法呢?记住这一点,除非其他选项在性能,可读性等方面更好,否则你应该遵守惯例.catch语句最初是为了处理异常类型的分类而拥有自己的,所以按原样使用它们......只是一个想法!...