try catch finally 用法 - aspirant - 博客园 (cnblogs.com)
try catch finally的底层原理_lwd512768098的博客-CSDN博客
try、catch、finally、return执行顺序超详解析(针对面试题)_来盘海参炒面不要面的博客-CSDN博客
try { //执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容 }
catch { //除非try里面执行代码发生了异常,否则这里的代码不会执行 }
finally { //不管什么情况都会执行,包括try catch 里面用了return }
catch可以有多个,也可以没有,每个catch可以处理一个特定的异常。程序按照你catch的顺序查找异常处理块,如果找到,则进行处理,如果找不到,则向上一层次抛出。如果没有上一层次,则向用户抛出,此时,如果你在调试,程序将中断运行,如果是部署的程序,将会中止。
finally可以没有,也可以只有一个。即使你在try块内用return返回了,在返回前,finally总是要执行,这以便让你有机会能够在异常处理最后做一些清理工作,如关闭数据库连接等等。
package com.jxz.trycatch;
import org.junit.Test;
/**
* @Author jiangxuzhao
* @Description
* @Date 2023/6/17
*/
public class TryCatchTest {
public static void main(String[] args) {
System.out.println(f1());
}
public static String f1(){
try{
int i = 1/1;
}catch (Exception e){
System.out.println("catch exception...");
e.printStackTrace();
}finally {
System.out.println("finally..."); // finally无论如何都会执行
}
System.out.println("main continue..."); // 没有异常可以继续向下执行
return "f1"; // 最后方法返回f1
}
}
输出:
finally...
main continue...
f1
public static String f2(){
try{
int i = 1/0;
}catch (Exception e){
System.out.println("catch exception..."); // 捕获到异常
e.printStackTrace();
}finally {
System.out.println("finally..."); // finally无论如何都会执行
}
System.out.println("main continue..."); // 捕获完异常可以继续向下执行
return "f2"; // 最后方法返回f2
}
输出:
catch exception...
finally...
main continue...
f2
java.lang.ArithmeticException: / by zero
at com.jxz.trycatch.TryCatchTest.f2(TryCatchTest.java:32)
at com.jxz.trycatch.TryCatchTest.main(TryCatchTest.java:14)
总结:
即使try-catch中有return,也都会执行finally语句块;先执行try或者catch中的return(return中自带逻辑也要执行完),但不返回,将变量存入临时栈中,然后去执行finally语句块;如果finally中有return,则程序会在finally执行完后直接return了;如果没有,则会执行完finally后返回前面临时栈中的值。
参考try、catch、finally、return执行顺序超详解析(针对面试题)_来盘海参炒面不要面的博客-CSDN博客
先执行try块中return 语句(包括return语句中的表达式运算),但不返回;
执行finally语句中全部代码
最后执行try中return返回
示例:无异常
package com.jxz.trycatch;
/**
* @Author jiangxuzhao
* @Description
* @Date 2023/6/18
*/
public class TryCatchFinallyReturnTest {
public static void main(String[] args) {
System.out.println(f1());
// System.out.println(f2()); 下面的示例代码都自带这个打印
// System.out.println(f3());
}
public static int f1(){
int temp = 1;
try {
System.out.println(temp);
return temp;
} catch (Exception e) {
System.out.println(temp);
} finally {
++ temp;
System.out.println(temp);
}
return temp;
}
}
输出:121
先执行try中的打印为1,执行return,但是不返回;然后执行finally块,++temp,temp更新为2,同时打印为2;由于finally块中没有return语句,因此要返回try块中,返回其临时栈的值1,外层打印1.
程序先执行try,如果遇到异常执行catch块,最终都会执行finally中的代码块;
示例1:有异常
public static int f2(){
int temp = 1;
try {
System.out.println(temp);
int i = 1/0;
} catch (Exception e) {
System.out.println(temp);
return ++ temp;
} finally {
++ temp;
System.out.println(temp);
}
return temp;
}
输出:1132
先执行try中的打印为1;出现异常进入catch块,先打印1,然后执行return ++temp,temp目前为2,但是仍然不返回;最后执行finally块,++temp,此时temp更新为3,同时打印3;由于finally块中没有return语句,因此要返回catch块中,返回其临时栈中的值2,外层打印2.
示例2:无异常
public static int f3(){
int temp = 1;
try {
System.out.println(temp);
// int i = 1/0;
} catch (Exception e) {
System.out.println(temp);
return ++ temp;
} finally {
++ temp;
System.out.println(temp);
}
return temp;
}
输出:122
先执行try中的打印为1;再执行finally,++temp,temp更新为2,并打印为2;此时temp为2,返回为2,打印为2.
此时finally块的return值,就是代码执行完后的值
示例: 无异常
public static int f4() {
int temp = 1;
try {
System.out.println(temp);
return temp;
} catch (Exception e) {
System.out.println(temp);
} finally {
System.out.println(temp);
return ++temp;
}
}
输出:112
先执行try中的打印为1,和return语句,但是并不返回,然后执行fially块,打印temp为1,执行return语句,++temp,temp更新为2并返回外层;外层打印为2.
示例1:无异常:
public static int f5() {
int temp = 1;
try {
System.out.println(temp);
} catch (Exception e) {
System.out.println(temp);
return ++temp;
} finally {
System.out.println(temp);
return ++temp;
}
}
输出: 112
先执行try中的打印1;然后执行finally块中的打印1,++temp,temp更新为2,并从这里返回,外层打印2.
有异常:
public static int f6() {
int temp = 1;
try {
System.out.println(temp);
int i = 1/0;
} catch (Exception e) {
System.out.println(temp);
return ++temp;
} finally {
System.out.println(temp);
return ++temp;
}
}
输出: 1123
先执行try中的打印1;出现异常然后执行catch中的打印1,++temp,temp更新为2,将结果存起来没有返回;执行finally中的打印为2,++temp,temp更新为3,这里finally块中有return直接从此处返回,外层打印3.
参考java异常处理(二)—从字节码层面看throw关键字及try…catch…finally的实现_程序猿成长轨迹的博客-CSDN博客,其实底层就是将finally块的字节码复制了三份,这三份代码分别放在了不同位置
主要和字节码ireturn有关,参考try catch finally的底层原理_lwd512768098的博客-CSDN博客,finally语句中是否带return,差别体现在字节码ireturn语句前是iload_0还是iload_1。