前言
在开发过程中异常处理是经常用到的,相信大部分使用try、catch、finally的只知道try中出现异常catch中会捕获,finally块中代码何时都会执行。其中还有很多细微的知识点,接下来我们一起学习学习。
try、catch、finally执行顺序
try { | |
// try 主体 | |
} catch (FirstThrowableType $e) { | |
// 捕获异常主体 | |
} catch (\Exception $exception) { | |
// 捕获异常主体 | |
} finally { | |
// finally 主体 | |
} |
try块和catch块中逻辑基本相同,try中出现异常catch捕获异常并抛出,若catch中出现异常则跳转到finally,try或catch正常执行若存在return则先执行return的代码并保存返回值信息再执行finally,若finally中出现异常或包含return则执行结束,若无异常且没有return则会执行try或catch中的return或结束。整体执行流程如下:
代码说明与示例
当try-catch-finally中无return时,如果try块中出现异常则进入catch中,执行完catch中代码后进入finally,如果catch中出现异常仍然会执行finally代码块,finally块执行结束后抛出异常。try块中无异常时执行完try块直接执行finally。
以catch中抛出异常为例,代码如下:
# 热爱Java的Phper | |
public function test() | |
{ | |
$a = 1; | |
try { | |
$a = 1 / 0; | |
app('log')->info("try ======== res:".$a); | |
return $a; | |
} catch (\Exception $exception) { | |
$a++; | |
app('log')->info("catch ======== res:".$a); | |
return $a; | |
} finally { | |
$a++; | |
app('log')->info("finally ======== res:".$a); | |
return $a; | |
} | |
} |
输出结果:
输出:a=4 | |
[2022-06-17 06:27:14] local.INFO: catch ======== res:2 | |
[2022-06-17 06:27:14] local.INFO: finally ======== res:3 | |
public function test() | |
{ | |
$a = 1; | |
try { | |
return $a; | |
} catch (\Exception $exception) { | |
$a++; | |
app('log')->info("catch ======== res:".$a); | |
return $a; | |
} finally { | |
$a++; | |
app('log')->info("finally ======== res:".$a); | |
return $a; | |
} | |
} | |
输出:a=2 | |
[2022-06-17 06:33:39] local.INFO: finally ======== res:2 |
- 如果catch里面有return或者try里面有return,finally里面没有return,最后会return前面的第一个return,非finally代码段的return后面的代码是不执行的,finally代码段肯定会执行。
- 如果catch里面有return或者try里面有return,finally里面有return,非finally代码段的return后面的代码是不执行的,但是finally里面的return会覆盖前面return的值
总结
finally 使用的意义在于可以在其中处理一些资源的回收等操作。在 catch 中是不方便处理的,特别是在含有多个 catch 段的时候,相同的代码可能需要重复写几次。而且 finally 可以跨越 return 存在,也就是说即使在 catch 或者 try 的代码块中使用 return ,finally 还是会执行,这样就使得实现相同效果的代码量更加少。