首页 > 编程笔记 > Java笔记 阅读:7

Java finally用法详解(附带实例)

Java 语言提供了异常捕获的处理机制,可以帮助我们处理由异常引发的问题。一般情况下,异常捕获使用 try-catch 语句,但实际上一个完整的异常处理语句由 3 部分组成,即 try 语句块、catch 语句块和 finally 语句块,结构如下:
try {
    可能会产生异常的程序代码
}catch (异常类型 e) {
    发生异常后处理的程序代码1
}catch (异常类型 e) {
    发生异常后处理的程序代码2
} … catch (异常类型 e) {
    发生异常后处理的程序代码n
}
finally {
    最终执行的程序代码
}
从语法上来讲,当异常处理机制结构中出现 catch 语句块时 finally 语句块是可选的,当包含 finally 语句块时 catch 语句块是可选的,二者可以同时存在,也可以只存在其一。与 catch 语句块可以出现多次不同,finally 语句块只能出现一次。

finally用来做什么

finally 是最终执行的语句块,无论 try-catch 语句块中是否发生异常,finally 语句块中的代码都会被执行。也就是说,当希望程序中的某些语句无论程序是否发生异常都执行时,可以将这些语句打包成 finally 语句块。

在实际开发中,finally 语句块用于关闭文件或释放其他系统资源。当然,也有一些例外情况,就是在 try-catch 语句块中执行 System.exit(0) 语句,表示退出当前的 Java 虚拟机,Java 虚拟机停止,程序中的任何代码都不会再执行。

接下来,通过案例来演示 finally 语句块的使用:
public class Demo {
    public static void main(String[] args) {
        try {
            final int result = divide(5, 0); // 调用divide()方法
            System.out.println(result); // 打印结果
        } catch (ArithmeticException e) {
            System.out.println("捕获到了异常:" + e);
            return;
        } finally {
            System.out.println("开始执行finally块");
        }
        System.out.println("异常捕获结束");
    }

    // 下面的方法实现了两个整数相除
    public static int divide(int x, int y) {
        int result = x / y; // 定义一个变量result,记录两个数相除的结果
        return result; // 将结果返回
    }
}
程序的运行结果如下:

捕获到了异常:java.lang.ArithmeticException: / by zero
开始执行finally块

程序中在 catch 语句块中添加了 return 语句,return 语句的作用在于结束当前方法。从程序运行的结果中不难发现,finally 语句块中的程序仍会被执行,不会受 return 语句的影响,而 try-catch-finally 结构后面的代码就不会被执行。

由此我们不难看出,不管程序是否发生异常,也不论在 try 和 catch 语句块中是否使用 return 语句结束,finally 语句块都会被执行。

另外,finally 是在 return 后面的表达式运算完成之后才执行的,此时并没有直接返回运算值,而是先将返回值保存(假设保存在了内存 A 中),finally 中的代码的执行不会影响方法的返回值,仍是在 finally 执行之前内存 A 中的值,因此方法返回值是在 finally 执行之前就已经确定的。

接下来,通过案例对上述情况进一步说明:
public class Demo {
    public static int testReturn() { // 定义变量x
        int x = 1; // 定义变量x
        try {
            ++x; // ++在前时先运算
            return x; // 返回结果
        } finally {
            ++x; // ++在前时先运算
            System.out.println("finally: " + x); // 打印在finally中的结果
        }
    }

    public static void main(String[] args) {
        System.out.println("最终返回值: " + testReturn());
    }
}
程序的运行结果如下:

finally:3
最终返回值:2

程序中随着方法被调用,程序先执行 try 语句块中的 ++x,此时 x 的值为 2;然后执行 return 语句时,先将计算结果 2 保存;接着程序转而执行 finally 语句块中的 ++x,此时 x 的值为 3;执行完毕之后,再从内存中取出返回结果进行返回。因此,虽然 finally 中对变量 x 进行了 ++ 操作,但是没有影响最终的返回结果。

在finally中使用return

在 finally 中最好不要使用 return 语句,否则程序会提前退出,返回值不是 try 或 catch 语句块中保存的返回值。

接下来,我们在 try 和 finally 语句块中加 return 语句进行测试:
public class Demo {
    public static String testReturn() {
        try {
            return "我是try中的return";
        } finally {
            return "我是finally中的return";
        }
    }

    public static void main(String[] args) {
        System.out.println("返回结果:" + testReturn());
    }
}
程序的运行结果如下:

返回结果:我是finally中的return

程序最终输出的是 finally 中的 return 语句,而并不是 try 中的 return 语句,所以在 finally 中最好不要使用 return 语句。

相关文章