zoukankan      html  css  js  c++  java
  • try catch finally 执行顺序与抛错机制

    try catch finally 执行顺序与抛错机制

    一、结论

    1. try 先执行 ,若有报错,执行 catch

    2. 不管有没有异常 finally 肯定会执行

    3. try 和 catch 中 存在 return 或者 throwfinally 也会执行

    4. catch 中若报错:

      猜测先 暂存 catch 错误 ,等待 finally 执行完毕后,抛出错误

    5. catch 中若报错, finally 也报错:

      1. 猜测先 暂存 catch 错误 ,等待 finally 执行,发现 finally 存在错误,直接抛出 finally 的错误
      2. 抛出 catch 错误的程序不会执行,所以最终表示为 抛出 finally 错误,catch 错误不显示
    6. 在 try catch 中,如果碰到 return 语句:

      1. 先执行 return 语句表达式 ,但是执行结果会被 局部变量 暂存
      2. 之后执行 finally 内容,再执行 return 操作,返回 局部变量暂存 的结果
    7. try 或 catch 若有 return :

      暂存 return 的执行结果 ,等待 finally 执行完毕后,才返回 try 或 catch 中 return 的执行结果

    8. try 或 catch 若有 return ,finally 也有 return:

      1. 暂存 try 和 catch return 的执行结果 ,等待 finally 执行完毕
      2. finally 存在 return ,直接返回 finally 的 return 值,程序提前退出

    二、场景

    throw 的作用是手动中断程序,抛出一个异常,会被捕获

    以下的 制造一个异常 场景可以视为 throw 一个常量或者其他数据,所以 throw 的场景等同异常场景


    1、无错误情况

    1、正常执行
    2、在 try 中 return 一个 常量
    3、在 try 中 return 一个 常量, 在 finally 中 return 一个 常量
    

    2、有错误情况

    1、在 try 中 制造一个异常
    2、在 try、catch 中 各制造一个异常
    3、在 try、catch、finally 中 各制造一个异常
    
    4、在 try 中 制造一个异常, catch return 一个 常量
    5、在 try 中 制造一个异常, catch return 一个 常量,finally return 一个常量
    

    三、测试代码

    以下测试用例都执行

    console.log(test())
    

    1、正常执行

    let test = function() {
        try {
            console.log('try:>>', 1)
        } catch (e) {
            console.log('catch:>> ', e)
        } finally {
            console.log('finally:>> ')
        }
    }
    // 没有报错,正常输出
    // try:>> 1
    // finally:>> 
    // undefined
    

    2、在 try 中 return 一个 常量

    1. try 中 return 的结果被 局部变量 保存起来,执行 finally 之后再输出
    let test = function() {
        try {
            // 未定义 a
            console.log('try:>>', 1)
            return 2
        } catch (e) {
            console.log('catch:>> ', e)
        } finally {
            console.log('finally:>> ')
        }
    }
    
    // try:>> 1
    // finally:>> 
    // 2
    

    3、在 try 中 return 一个 常量, 在 finally 中 return 一个 常量

    1. try return 的值被 局部变量 保存起来,执行 finally 之后,
    2. 发现 finally 中存在 return ,直接 返回 finally 的 return 结果,程序提前退出
    let test = function() {
        try {
            console.log('try:>>', 1)
            return 2
        } catch (e) {
            console.log('catch:>> ', e)
        } finally {
            console.log('finally:>> ')
            return 3
        }
    }
    
    // try:>> 1
    // finally:>> 
    // 3
    

    4、在 try 中 制造一个异常

    1. try 异常被 catch 捕获,输出 try 异常,继续执行 finally
    let test = function() {
        try {
            console.log('try:>>', a)
        } catch (e) {
            console.log('catch:>> ', e)
        } finally {
            console.log('finally:>> ')
        }
    }
    // catch:>>  ReferenceError: a is not defined
    // finally:>> 
    // undefined
    

    5、在 try、catch 中 各制造一个异常

    1. try 异常被 catch 捕获,此时catch 异常,猜测先 暂存 catch 错误 ,等待 finally 执行完毕后,抛出 catch 错误
    let test = function() {
        try {
            console.log('try:>>', a)
        } catch (e) {
            console.log('catch:>> ', e)
            console.log('catch:>> ', b)
        } finally {
            console.log('finally:>> ')
        }
    }
    
    // catch:>>  ReferenceError: a is not defined
    // finally:>> 
    // ReferenceError: b is not defined
    

    6、在 try、catch、finally 中 各制造一个异常

    1. try 异常被 catch 捕获,此时 catch 异常,猜测先 暂存 catch 错误 ,等待 finally 执行,发现 finally 存在错误,直接抛出 finally 的错误
    2. 抛出 catch 错误的程序不会执行,所以最终表示为 抛出 finally 错误,catch 错误不显示
    let test = function() {
        try {
            console.log('try:>>', a)
        } catch (e) {
            console.log('catch:>> ', e)
            console.log('catch:>> ', b)
        } finally {
            console.log('finally:>> ')
            console.log('finally:>> ', c)
        }
    }
    
    // catch:>>  ReferenceError: a is not defined
    // finally:>> 
    // ReferenceError: c is not defined
    
    

    7、在 try 中 制造一个异常, catch return 一个 常量

    1. try 异常被 catch 捕获, 局部变量暂存 catch return 的执行结果
    2. 执行 finally 之后,返回 局部变量暂存的结果
    let test = function() {
        try {
            console.log('try:>>', a)
        } catch (e) {
            console.log('catch:>> ', e)
            return 1
        } finally {
            console.log('finally:>> ')
        }
    }
    
    // catch:>>  ReferenceError: a is not defined
    // finally:>> 
    // 1
    
    

    8、在 try 中 制造一个异常, catch return 一个 常量,finally return 一个常量

    1. try 异常被 catch 捕获, 局部变量暂存 catch return 的执行结果 ,等待 finally 执行完毕
    2. finally 存在 return ,直接返回 finally 的 return 值,程序提前退出
    let test = function() {
        try {
            console.log('try:>>', a)
        } catch (e) {
            console.log('catch:>> ', e)
            return 1
        } finally {
            console.log('finally:>> ')
            return 2
        }
    }
    
    // catch:>>  ReferenceError: a is not defined
    // finally:>> 
    // 2
    

    9、验证 try return 后,结果暂存,执行 finally 后,最后返回暂存结果

    let test = function() {
        let x = 1
        try {
            // 此处 执行 ++x 表达式, x = 2,但是程序不会直接返回结果
            // 而是会使用 局部变量 缓存 return 的值 2 
            // 等待 finally 执行完成后,再 return 缓存的 局部变量值
            return ++x
        } catch (e) {
            
        } finally {
            // 这里 x = 3
            // x 变成了 3,但是最终函数执行的返回值是 2
            ++x
        }
        // 因为上面 return ,此处不执行
        console.log('x :>> ', x);
        return x
    }
    // 最后输出结果为: 2
    // 分析:
    // 1、
    // try 执行 ++x 表达式, x = 2,但是程序不会直接返回结果
    // 而是会使用 局部变量 缓存 return 的值 2 
    
    // 2、
    // 执行 finally
    // x = 3
    
    // 3、
    // finally 执行完成后, return 缓存的 局部变量值 2
    // 最后输出结果为 2
    
  • 相关阅读:
    Tensorflow遇到的问题
    IPAdr2023网络计算器IP Address Computer Edition 2023 download
    AtomCalcor 2022 原子计算器下载Atom Calcor Edition 2022 download
    js对手机软键盘的监听
    GDB 命令行调试之路(全 19)
    URLConnection 的陷阱 java_关于connection reset 服务器cgi
    详解KMP算法 另一种思路
    EF中提示一个或者多个验证出现错误,查看 EntityValidationErrors 详细信息的解决方法
    C#中数字日期转中文小写日期
    想要淘便宜淘白菜的请访问 http://31tj.com
  • 原文地址:https://www.cnblogs.com/linjunfu/p/12850555.html
Copyright © 2011-2022 走看看