zoukankan      html  css  js  c++  java
  • Java内部抛出异常外部不能catch问题分析

    今天在论坛看到一篇关于异常处理的文章,异常处理机制详解开头就搬出了这样一个例子:

    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, catch exception
    testEx1, finally; return value=false
    testEx, finally; return value=false

    很多人诧异的一点是testEx2明明抛出了异常throw e,为什么外层异常处理器没有其作用,文章并没有谈及,不知道是作者谦虚还是留给大家去探索。本文不聊一些基础性的东西,因为网上这种文章太多,我没必要重复去说,我只想分析一下为什么是这样的一个打印结果。

    package Test;  
    
    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();  // 内部异常已被finally 的return 屏蔽
                if (!ret) {  
                    return false;  
                }  
                System.out.println("testEx1, at the end of try");  
                return ret;  
            } catch (Exception e) {  
            // 异常处理器无效,此处代码跳过直接finally
                System.out.println("testEx1, catch exception");  
                ret = false;  
                throw e;  
            } finally {  
                System.out.println("testEx1, finally; return value=" + ret);  
                return ret;  // 同理如果此处的return 被拿掉则不会屏蔽掉throw e ,关键就看当前函数的最后一条语句是return 还是 throw
            }  
        }  
    
        boolean testEx2() throws Exception {  
            boolean ret = true;  
            try {  
                int b = 12;  
                int c;  
                for (int i = 2; i >= -2; i--) {  
                    c = b / i;  
                     // 1.首先打印2递减    打印i=2 , i=1
                    System.out.println("i=" + i);   // 当i=0 运行时异常抛出
                }  
                return true;  
            } catch (Exception e) { 
                  // 2. Exception 包含除Error外的所有运行时异常,能够处理抛出异常 打印  testEx2, catch exception
                System.out.println("testEx2, catch exception");  
                ret = false;  
               //  3. 程序要抛出异常但是有finally子句,需要执行
                throw e;  
            } finally {  
                // 4. 打印
                System.out.println("testEx2, finally; return value=" + ret); 
               // 5. 此处return JVM认定此函数能够正常响应 屏蔽throw e子句 ,如果此处不是return 子句,外层catch能捕获异常,因为JVM会认定此函数没有return , 返回异常
                return ret;  
            }  
        }  
    
        public static void main(String[] args) {  
            TestException testException1 = new TestException();  
            try {  
                testException1.testEx();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }

    JVM根据try - catch -> finally语句的执行顺序,看最后返回的是throw还是return来判断是正常返回还是抛出异常。

  • 相关阅读:
    Python之路【第十九篇】:前端CSS
    大数据之路【第十五篇】:数据挖掘--推荐算法
    大数据之路【第十四篇】:数据挖掘--推荐算法(Mahout工具)
    Python之路【第十八篇】:前端HTML
    大数据之路【第十三篇】:数据挖掘---中文分词
    大数据之路【第十二篇】:数据挖掘--NLP文本相似度
    Python之路【第十七篇】:Python并发编程|协程
    Python之路【第十六篇】:Python并发编程|进程、线程
    大数据之路【第十篇】:kafka消息系统
    Python之路【第十五篇】开发FTP多线程程序
  • 原文地址:https://www.cnblogs.com/jpfss/p/9454882.html
Copyright © 2011-2022 走看看