finally相关知识
-
try catch finally直接看代码:代码一:public class Test { public static void main(String[] args) { System.out.println(new Test().test()); } static int test() { int x = 1; try { return x; } finally { ++x; } }}结果:1这说明了什么问题?finally块里面的代码总是在try块return之后执行?我们将代码稍作修改代码二:public class Test { public static void main(String[] args) { System.out.printl
-
Java finally 的用法,看这一篇就够了本文得到 baeldung team 的翻译许可 英文原文:https://www.baeldung.com/java-finally-keyword 1.概述 在本教程中,我们将研究 Java 中的 finally 关键字的用法。 我们将看到如何在错误处理中与 try / catch 块一起使用它。 尽管 finally 的目的是保证代码被执行,但是我们还将讨论 JVM 不执行 finally 代码的特殊情况。 我们还将讨论一些常见的陷阱,在这些陷阱中,finally 块可能会产生意外的结果。 2.什么是finally try 关键字最后可以定义 finally 代码块。
-
有return的情况下try-catch-finally的执行顺序概述: 不管有木有出现异常,finally块中代码都会执行; 当try和catch中有return时,finally仍然会执行; finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的; finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。 举例: 情况1:try{} catch(){}finally{} return; 显然程序按顺
-
有return的情况下try catch finally的执行顺序有return的情况下try catch finally的执行顺序(最有说服力的总结) 结论: 1、不管有没有出现异常,finally块中代码都会执行; 2、当try和catch中有return时,finally仍然会执行; 3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的; 4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中
finally相关课程
finally相关教程
- 4. finally() finally 是 ES9 的规范,它也是 then 的一个别名,只是这个方法是一定会执行的,不像上面提到的 catch 只有在上一层抛出异常或是执行 reject 时才会走到 catch 中。Promise.resolve('123').finally(() => { console.log('100') // 100})知道 finally 是 then 的一个别名,那我们就知道在它后面也是可以链式调用的。Promise.resolve('123').finally(() => { console.log('100') return 200}).then((data) => { console.log(data) // 123})需要注意的是在 finally 中返回的普通值或是返回一个 Promise 对象,是不会传到下一个链式调用的 then 中的。如果 finally 中返回的是一个异步的 Promise 对象,那么链式调用的下一层 then 是要等待 finally 有返回结果后才会执行:Promise.resolve('123').finally(() => { console.log('100') return new Promise((resolve, reject) => { setTimeout(() => { resolve(100) }, 3000) })}).then((data) => { console.log(data) // 123})执行上面的代码,在 then 中打印的结果会在 3 秒后执行。这也说明了 finally 有类似 sleep 函数的意思。finally 是 ES9 的规范,在不兼容 ES9 的浏览器中就不能使用这个 api,所以我们可以在 Promise 对象的原型上增加一个 finally 方法。Promise.prototype.finally = function(callback) { return this.then((value) => { return Promise.resolve(callback()).then(() => value); }, (err) => { return Promise.reject(callback()).catch(() => {throw err}); })}因为 finally 是一定会执行的,所以 then 中的成功和失败的回调都需要执行 finally 的回调函数。使用 Promise.resolve(value) 和 Promise.reject(reason) 去执行 finally 传入的回调函数,然后使用 then 和 catch 来返回 finally 上一层返回的结果。
- 4.1 基本用法 在异常处理中,finally 关键字用于指定无论是否发生异常都需要执行的代码块,语法如下:try: 可能发生异常的代码块except: 处理异常的代码块finally: 无论是否发生异常都会执行的代码块下面的程序在执行过程中没有异常:try: print('try:')finally: print('finally:')程序输出:try:finally:下面的程序在执行过程中产生异常:try: print('try:') 100 / 0finally: print('finally:')程序输出:try:finally:可以看出,无论是否发生异常,finally 定义的代码块总是被执行。
- 5. 捕获异常 使用 try 和 catch 关键字可以捕获异常。try catch 代码块放在异常可能发生的地方。它的语法如下:try { // 可能会发生异常的代码块} catch (Exception e1) { // 捕获并处理try抛出的异常类型Exception} catch (Exception2 e2) { // 捕获并处理try抛出的异常类型Exception2} finally { // 无论是否发生异常,都将执行的代码块}我们来看一下上面语法中的 3 种语句块:try 语句块:用于监听异常,当发生异常时,异常就会被抛出;catch 语句块:catch 语句包含要捕获的异常类型的声明,当 try 语句块发生异常时,catch 语句块就会被检查。当 catch 块尝试捕获异常时,是按照 catch 块的声明顺序从上往下寻找的,一旦匹配,就不会再向下执行。因此,如果同一个 try 块下的多个 catch 异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面;finally 语句块:无论是否发生异常,都会执行 finally 语句块。finally 常用于这样的场景:由于 finally 语句块总是会被执行,所以那些在 try 代码块中打开的,并且必须回收的物理资源(如数据库连接、网络连接和文件),一般会放在 finally 语句块中释放资源。try 语句块后可以接零个或多个 catch 语句块,如果没有 catch 块,则必须跟一个 finally 语句块。简单来说,try 不允许单独使用,必须和 catch 或 finally 组合使用,catch 和 finally 也不能单独使用。实例如下:public class ExceptionDemo3 { // 打印 a / b 的结果 public static void divide(int a, int b) { System.out.println(a / b); } public static void main(String[] args) { try { // try 语句块 // 调用 divide() 方法 divide(2, 0); } catch (ArithmeticException e) { // catch 语句块 System.out.println("catch: 发生了算数异常:" + e); } finally { // finally 语句块 System.out.println("finally: 无论是否发生异常,都会执行"); } }}运行结果:catch: 发生了算数异常:java.lang.ArithmeticException: / by zerofinally: 无论是否发生异常,都会执行运行过程:divide() 方法中除数 b 为 0,会发生除零异常,我们在方法调用处使用了 try 语句块对异常进行捕获;如果捕获到了异常, catch 语句块会对 ArithmeticException 类型的异常进行处理,此处打印了一行自定义的提示语句;最后的 finally 语句块,无论发生异常与否,总会执行。Java 7 以后,catch 多种异常时,也可以像下面这样简化代码:try { // 可能会发生异常的代码块} catch (Exception | Exception2 e) { // 捕获并处理try抛出的异常类型} finally { // 无论是否发生异常,都将执行的代码块}
- 4. try … finally 语句
- 6. ReentrantLock 验证锁的可重入性 相同的场景,对代码进行如下改造,将 synchronized 同步代码块修改成 lock 接口同步,我们看代码实例如下:public class DemoTest { public static void main(String[] args) { new Thread(new SynchronizedTest()). start(); }}class SynchronizedTest implements Runnable { private final Lock lock = new ReentrantLock(); public void helloA() { //方法1,调用方法2 lock.lock(); try { System.out.println(Thread.currentThread().getName() + " helloA()"); helloB(); } finally { lock.unlock(); } } public void helloB() { lock.lock(); try { System.out.println(Thread.currentThread().getName() + " helloB()"); } finally { lock.unlock(); } } @Override public void run() { helloA(); }}结果验证:Thread-0 helloA()Thread-0 helloB()结果解析:ReentrantLock 一样是可重入锁,试验成功。
- 6. 编程案例 上面介绍了核心编程方法,我们举一个编程案例,实际体会一下 ReentrantReadWriteLock 的用法。import lombok.SneakyThrows;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockTest { // 创建读写锁对象 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); // 获取读锁对象 private final Lock readlock = readWriteLock.readLock(); // 获取写锁对象 private final Lock writelock = readWriteLock.writeLock(); // 待控制的资源 private int account = 0; private static ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest(); public static void main(String[] args) { new Thread(new Runnable() { @SneakyThrows public void run() { while(true) { Thread.sleep(1000); int tmp = readWriteLockTest.get(); System.out.println("读操作:" + tmp); } } }).start(); new Thread(new Runnable() { @SneakyThrows public void run() { while(true) { Thread.sleep(2000); readWriteLockTest.add(10); } } }).start(); } public void add(int value) { // 加写锁 writelock.lock(); try { account += 1; } finally { // 释放写锁 writelock.unlock(); } } public int get() { // 加读锁 readlock.lock(); try { return account; } finally { // 释放读锁 readlock.unlock(); } }}运行上面代码一段时间后结果如下:读操作:0读操作:1读操作:1读操作:2读操作:2注意在使用时,获取锁的操作 lock () 应该放在 try 之前,而释放锁的操作 unlock () 需要放在 finally 中,可确保锁释放。
finally相关搜索
-
face
fade
fadein
fadeout
fadeto
fail
family
fastcgi
fastjson
fault
fclose
fdisk
feed
fetch
ff浏览器
fgets
fields
fieldset
fighting
figure