Java 异常处理问题

Java 异常处理问题,java,exception-handling,Java,Exception Handling,我有一个关于异常处理的问题。 考虑下面的java代码片段。 try{ //code }catch(SubSubException subsubex){ //code }catch(SubException subex){ //code }catch(Exception ex){ //code } try{

我有一个关于异常处理的问题。 考虑下面的java代码片段。
        try{
            //code
        }catch(SubSubException subsubex){
            //code
        }catch(SubException subex){
            //code
        }catch(Exception ex){
            //code
        }
        try{
            //code
        }catch ( Exception ex){
            if( ex instanceof SubException){              
                //code
            }else if(ex instanceof SubSubException){
                //code
            }else{
                //code
            }
        }
我知道这是处理异常的推荐方法。但我可以通过使用下面的代码片段实现同样的功能

        try{
            //code
        }catch(SubSubException subsubex){
            //code
        }catch(SubException subex){
            //code
        }catch(Exception ex){
            //code
        }
        try{
            //code
        }catch ( Exception ex){
            if( ex instanceof SubException){              
                //code
            }else if(ex instanceof SubSubException){
                //code
            }else{
                //code
            }
        }

谁能告诉我第二种方法的缺点吗?

第二种方法可读性较差。此外,口袋妖怪异常处理从来都不是一个好办法,即使你的“聪明”技巧是使用instanceof关键字。无论如何,我不是在开玩笑或嘲笑你,但最好是为人类编写代码来阅读和维护,而不是为计算机编写代码。

嗯,你为什么还要使用第二种方法呢?记住这一点,除非其他选项在性能、可读性等方面更好,否则您应该遵守约定。catch语句最初的设计目的是让它们自己处理异常类型的分类,所以按原样使用它们。。。只是一个想法

考虑到第一个块中的代码测试异常的类型,测试一次基本异常(在第二个代码位中,您将以某种方式测试两次基本异常),并且缩进更少(因此逻辑更少),我认为第一个块更好,更容易理解,等等

缺点:
-更难理解的是,在第二个示例中,在重新排序异常的“捕获”时,将其作为旁白。如果SubSubException扩展了SubException,则永远不会进行第二次检查

只是在订购渔获物时要小心的一点


除此之外,正如其他地方所提到的,问题是当第一种方法起作用时,为什么要尝试第二种方法,因为第一种方法是标准的且可读的?

第二种情况是完全有效的java代码,但它的可读性更大,而不增加任何额外的值。

第二种方法的可读性要低得多,因为:

  • 它需要更多的符号

  • 它需要更深的压痕

  • 这不是惯用语


在国际海事组织,最后一个是最重要的。您应该以其他Java程序员期望的方式编写代码。

是的,MadMurf指出了最重要的区别:编译时的可达性检查。标准的习惯用法会捕获类似的内容,并正确地阻止其编译:

    try {
    } catch (IndexOutOfBoundsException iooe) {
    } catch (ArrayIndexOutOfBoundsException aiooe) {
    }
原始问题中提出的if/instanceof模拟将编译(这不是您想要的,因为它是错误的)

中给出了标准习惯用法在编译时捕获错误的原因

  • 当以下两项均为真时,可到达捕捉块C:
    • [……]
    • try语句中没有较早的catch块A,因此C的参数类型与A的参数类型相同或是A的参数类型的子类
为了进一步说明这一点,汇编如下:

    try {
    } catch (Exception e) {
        if (e instanceof Exception) {
        } else if (e instanceof Exception) {
        }
    }
正如您所看到的,这种“pokemoncatching”习惯用法更难维护,因为它绕过了标准习惯用法中强制执行的一些编译时可达性检查

为了更清楚地说明这一点,无论你是有意还是无意,你实际上重新安排了检查原始问题中例外情况的顺序,这一事实很容易被其他人忽略。如果SubSubException是SubException的子类,则第二个If条件将永远不会被计算,其主体实际上是不可访问的代码

if/instanceof方法很容易出错。

我认为更好(可读性更好):


从未听说过它被称为口袋妖怪异常处理-我喜欢它。我只希望它流行起来:)我想知道“口袋妖怪异常处理”也来自哪里…:o) 我也喜欢+1提到“最好编写代码供人类阅读和维护”。没错。我们应该把“口袋妖怪异常处理”变成官方的反模式!那是我的错我误读了你说的。。。对不起,我不能把它拿走:(@ultrajohn:对你的答案进行一次虚拟编辑,这样@woot4moo就可以删除他的反对票:)@woot4,没关系,我理解:)其他人的观点是正确的,但这是最好的答案。作为程序员,我们永远不应该做编译器能为我们做的工作。这应该被接受。目前公认的答案只涉及可读性和风格。允许编译器检查更多是正确的答案。