_092_Java_finally中使用return会吃掉catch中抛出的异常

转自finally中使用return会吃掉catch中抛出的异常_天天的博客-CSDN博客,感谢作者的无私分享。

如果在finally中使用return,会吃掉catch中抛出的异常,也会吃掉try或者catch中的return。

如果在finally中使用throw,会吃掉catch中抛出的异常,也会吃掉try或者catch中的return。

看例子:

public class TestException {  

    public TestException() {  

    }  


    boolean testEx() throws Exception {  

        boolean ret = true;  

        try {  

            ret = testEx1();  

        } catch (Exception e) {  

            System.out.println("testEx, catch exception");  

            ret = false;  

            throw e;  

        } finally {  

            System.out.println("testEx, finally; return value=" + ret);  

            return ret;  

        }  

    }  


    boolean testEx1() throws Exception {  

        boolean ret = true;  

        try {  

            ret = testEx2();  

            if (!ret) {  

                return false;  

            }  

            System.out.println("testEx1, at the end of try");  

            return ret;  

        } catch (Exception e) {  

            System.out.println("testEx1, catch exception");  

            ret = false;  

            throw e;  

        } finally {  

            System.out.println("testEx1, finally; return value=" + ret);  

            return ret;  

        }  

    }  


    boolean testEx2() throws Exception {  

        boolean ret = true;  

        try {  

            int b = 12;  

            int c;  

            for (int i = 2; i >= -2; i--) {  

                c = b / i;  

                System.out.println("i=" + i);  

            }  

            return true;  

        } catch (Exception e) {  

            System.out.println("testEx2, catch exception");  

            ret = false;  

            throw e;  

        } finally {  

            System.out.println("testEx2, finally; return value=" + ret);  

            return ret;  

        }  

    }  

  
    public static void main(String[] args) {  

        TestException testException1 = new TestException();  

        try {  

            testException1.testEx();  

        } catch (Exception e) {  

            e.printStackTrace();  

        }  

    }  

}  


运行结果:

i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, finally; return value=false
testEx, finally; return value=false

有点奇怪,下层方法抛出的异常竟然没有被捕获。

如果把return和throw放在一起,直接会提示错误。"Unreachable statement"(无法被执行).

然而finally却可以成功骗过编译器让两者并存(是不是可以算是编译器的一个小bug呢),结果是后执行的会覆盖前者。finally如果有return会覆盖catch里的throw,同样如果finally里有throw会覆盖catch里的return。

进而如果catch里和finally都有return finally中的return会覆盖catch中的。throw也是如此。

这样就好理解一些了,retrun和throw都是使程序跳出当前程序的方法,自然就是冲突的。如果非要跳出两次那么后者会覆盖前者。

在《java编程思想》中也有类似的例子,放在这里一起讨论。

“9.6.2 缺点:丢失的违例
一般情况下,Java的违例实施方案都显得十分出色。不幸的是,它依然存在一个缺点。尽管违例指出程序里存在一个危机,而且绝不应忽略,但一个违例仍有可能简单地“丢失”。在采用finally从句的一种特殊配置下,便有可能发生这种情况”

class VeryImportantException extends Exception{

    public String toString(){

        return "A very important exception";

    }

}


class HoHumException extends Exception{

    public String toString() {

        return "A trivial exception";

    }

}

public class LostMessage {

    void f() throws VeryImportantException{
    
        throw new VeryImportantException();

    }


    void dispose() throws HoHumException{

        throw new HoHumException();

    }


    public static void main(String[] args) throws Exception{

        LostMessage lm = new LostMessage();

        try{

            lm.f();

        }finally {

            lm.dispose();

        }

    }

}


输出:

Exception in thread "main" A trivial exception
at com.test.exception.LostMessage.dispose(LostMessage.java:24)
at com.test.exception.LostMessage.main(LostMessage.java:32)
 

“这是一项相当严重的缺陷,因为它意味着一个违例可能完全丢失。而且就象前例演示的那样,这种丢失显得非常“自然”,很难被人查出蛛丝马迹。而与此相反,C++里如果第二个违例在第一个违例得到控制前产生,就会被当作一个严重的编程错误处理。或许Java以后的版本会纠正这个问题(上述结果是用Java 1.1生成的)。”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值