美文网首页
《Java编程思想》笔记——异常

《Java编程思想》笔记——异常

作者: Brian512 | 来源:发表于2017-01-18 17:05 被阅读19次

    异常

    发现错误的理想时机是在编译阶段

    Throwable这个Java类被用来表示任何可以作为异常被抛出的类。Throwable对象可分为两类:

    • Error用来表示编译时和系统错误;
    • Exception是可以被抛出的基本类型。

    Java中异常处理的常用结构如下:

        public static int testFinally() {
            try {
                System.out.println("try");
                return testReturn1();
            } catch (Exception e) {
                System.out.println("catch");
                e.getStackTrace(); // 该方法返回一个由栈轨迹中的元素所构成的数组
                e.printStackTrace(); // 该方法将上面方法返回的数组输出
                return 2;
            } finally {
                System.out.println("finally");
                return testReturn3();
            }
    //      return 4; // Error: Unreachable code
        }
    
        public static int testReturn1() {
            System.out.println("return1");
            return 1;
        }
    
        public static int testReturn3() {
            System.out.println("return3");
            return 3;
        }
    
    // 该方法返回值为:3
    
    • 无论try块中的异常是否抛出,finally子句都能得到执行,但是finally子句在某些场景下并不能得到执行(多线程中断等)。
    • 异常处理系统会按照代码的书写顺序找出“最近”的处理程序。
    • 若在catch子句中不处理异常,则异常就像丢失了一样。
    • RuntimeException被称为“不受检查异常”,这种异常输出错误,将被自动捕获。

    下面探究一下finally与return的执行顺序

        public static void main(String[] args) {
            System.out.println(testFinally());
        }
    
        public static int testFinally() {
            try {
                System.out.println("try");
                return testReturn1();
            } catch (Exception e) {
                System.out.println("catch");
                return 2;
            } finally {
                System.out.println("finally");
                return testReturn3();
            }
    //      return 4; // Error: Unreachable code
        }
    
        public static int testReturn1() {
            System.out.println("return1");
            return 1;
        }
    
        public static int testReturn3() {
            System.out.println("return3");
            return 3;
        }
    
    ///
    try
    return1
    finally
    return3
    3
    

    从这个输出可以看出,try块中的return会执行,但是最终的返回值却是3,也就是finally里面返回的那个值。那么问题来了,try块的return的值去哪里了?

        public static void main(String[] args) {
            System.out.println(testFinally());
        }
    
        private static int n = 1;
        public static int testFinally() {
            try {
                return n;
            } catch (Exception e) {
                return 2;
            } finally {
                n = 3;
            }
        }
    
    ///
    1
    

    上面的测试就是猜想,若是try块中的return值并不会返回,那么我特意在finally中改变n的值,期望最终的返回值为修改后的3,但是结果确实修改前的1.
    最终猜想执行顺序:
    1. 执行:try的return,结果保存在操作数栈顶;
    2. 执行:操作数栈顶值(try的return值)复制到局部变量区作为返回值;
    3. 执行:finally语句块中的代码;
    4. 执行:将第2步复制到局部变量区的返回值又复制回操作数栈顶;
    5. 执行:return指令,返回操作数栈顶的值;
    若finally中有return操作,则第4步就会把finally的return值存放到操作数栈顶。


    持续完善补充!

    相关文章

      网友评论

          本文标题:《Java编程思想》笔记——异常

          本文链接:https://www.haomeiwen.com/subject/ibkbbttx.html