1、try块中有return时,finally块依旧可以执行
public static int test1() {
try {
return 1;
} finally {
System.out.println("try中有return时,finally块依旧可以执行,且在return之前执行");
}
}
执行结果:

2、catch块中有return时,finally依旧可以执行
public static int test2() {
try {
//此处制造异常
int a = 1 / 0;
return 1;
} catch (Exception e) {
return 2;
} finally {
System.out.println("catch中有return时,finally块依旧可以执行,且在return之前执行");
}
}
执行结果:

3、finally中也有return时,会直接返回,此时忽略try/catch中的return
public static int test3() {
try {
//此处制造异常
int a = 1 / 0;
return 1;
} catch (Exception e) {
return 2;
} finally {
System.out.println("执行finally的return");
return 3;
}
}
执行结果:

4、finally中修改返回的变量(基本数据类型)
public static int test4() {
int i = 0;
try {
i = 1;
return i;
} finally {
System.out.println("在finally块中修改i的值为3");
i = 3;
}
}
执行结果:

5、在catch块中修改返回变量值(基本数据类型)
public static int test5() {
int i = 0;
try {
i = 1;
//此处制造异常
int a = 1 / 0;
return i;
} catch (RuntimeException e) {
System.out.println("在finally块中修改i的值为2");
i = 2;
return i;
} finally {
System.out.println("在finally块中修改i的值为3");
i = 3;
}
}
执行结果:

6、finally中修改返回引用类型的属性值(引用类型:自定义的Person类)
@Data
@ToString
@AllArgsConstructor
public class Person {
/**
*
* 使用了lombok注解
* @ToString 自动重写toString方法
* @Data 自动写属性的getter和setter方法
* @AllArgsConstructor 创建包含所有参数的构造函数
* */
private String name;
private int age;
}
创建一个person对象传参调用:
public static void main(String[] args) {
Person person = new Person("精神小伙", 18);
System.out.println(test6(person));
}
public static Person test6(Person person) {
try {
person.setAge(20);
person.setName("精神不起来");
return person;
} finally {
System.out.println("在finally块中修改person属性值");
person.setAge(18);
person.setName("精神小伙");
}
}
执行结果:此时修改的是引用变量的属性,而不是引用变量自身。

7、finally中修改返回的引用类型变量(引用类型:自定义的Person类)
public static Person test7(Person person) {
try {
person.setAge(20);
person.setName("精神不起来");
return person;
} finally {
System.out.println("在finally块中修改person引用");
person = new Person("精神小伙", 18);
}
}
执行结果:此时修改的是引用变量

8、在finally中修改返回变量(String)
public static String test8() {
String s = "";
try {
s = "string";
return s;
} finally {
//return时已经记录s的地址,
//当前操作为将s指向别的地址,故对返回值无关
s = "update string";
System.out.println("在finally块修改string值");
}
}
执行结果:

9、一道面试题
public class Test {
private static String result = "";
public static void main(String[] args) {
test(1);
//这句是我加的,方便分析流程
result += "*";
test(0);
System.out.println(result);
}
public static void test(int i) {
result += "1";
try {
if (i == 0) {
throw new RuntimeException("");
}
result += "2";
} catch (Exception e) {
result += "3";
//这里只是终止程序,不要看错了
return;
} finally {
result += "4";
}
result += "5";
}
}
执行结果:

分析:test()方法没有返回值,所以在所有的try/catch/finally之后底下的语句也要执行!!!有时候上面的返回值看久了,一直觉得要返回,自己把底下的语句忽略了。
第一次执行:不抛出异常,所以除了catch中的语句不执行,其他都执行;则得出结果result = 1245
第二次执行:此时的result = 1245*;这次抛出异常,result+=2语句在抛出异常之后,所以不会执行;并且在catch块中赋值语句执行完之后,终止程序。所以,最后的result+="5"不会执行;最后可以得出最终的结果是1245*134
来源:CSDN
作者:文以.
链接:https://blog.csdn.net/qq_35732831/article/details/104789779