一、情况的分类
1、从代码结构看:
finally中进行return与不进行return
ps: 如果代码中只有一处return,只能出现在finally中或者整个try catch finally框架之外。
2、是否在finally中改变变量值
二、案例说明
自定义描述术语:
return生效:因为在try catch finally框架中,很有可能出现准备返回但未返回的情况(因为必须执行finally中的代码),不同位置上的return语句生效的情况不一样。
假设:
存在两处return,一处return a,一处return b。
情况说明:
有可能是return a生效,有可能是return b生效,从而导致最终的返回结果是不相同的。
ps: 当第一次执行到某个return语句时,会返回的值已经确定了。例如先执行到return a,如果后面不改变生效的return语句,那么就会返回a。
三、代码说明
情况一:try中有return,finally中没有return
public class ReturnDemo01 {
public static void main(String[] args) {
System.out.println(test());
}
private static int test(){
int num = 10;
try{
System.out.println("try");
return num += 80;//此时num已经变成90,所以可以执行finally代码块中的if语句
}catch(Exception e){
System.out.println("error");
}finally{
if (num > 20){
System.out.println("num>20 : " + num);
}
System.out.println("finally");
}
return num;
}
}
/**
* 结果:
* try
* num>20 : 90
* finally
* 90
*/
情况二:try和finally中均有return
finally中的return语句先于try中的return语句执行,也就是前面所说的return生效的语句发生变换
public class ReturnDemo02 {
public static void main(String[] args) {
System.out.println(test());
}
private static int test(){
int num = 10;
try{
System.out.println("try");
return num += 80;
}catch(Exception e){
System.out.println("error");
}finally{
if (num > 20){
System.out.println("num>20 : " + num);
}
System.out.println("finally");
num += 20;
System.out.println(num);//想看看这里对num的操作是基于try中已有的基础(80),还是初始值(10)
//发现是前者
return num;//10+80+20
}
}
}
/**
* 结果:
* try
* num>20 : 90
* finally
* 110
* 110
*/
情况三:finally中改变返回值num
public class ReturnDemo03 {
public static void main(String[] args){
System.out.println(test());//10
}
private static int test(){
int num = 10;
try{
System.out.println("try");
return num;//因为finally中没有return语句,所以在此返回
}catch(Exception e){
System.out.println("error");
}finally{
if (num > 20){
System.out.println("num>20 : " + num);
}
System.out.println("finally");
num = 100;
}
return num;
}
}
/**
* 结果:
* try
* finally
* 10
*/
情况四:将num的值包装在Num类中
实际上操作的是一个对象,也只能返回同一个对象,又因为是引用型变量,所以区别于情况三,可以进行改变。
public class Num {
public int num = 10;
}
public class ReturnDemo04 {
public static void main(String[] args){
System.out.println(test().num);
}
private static Num test(){
Num number = new Num();//num=10
try{
System.out.println("try");
return number;
}catch(Exception e){
System.out.println("error");
}finally{
if (number.num > 20){
System.out.println("number.num>20 : " + number.num);
}
System.out.println("finally");
number.num = 90;
}
return number;
}
}
/**
* 结果:
* try
* finally
* 90
*/
小结: (对情况三+情况四)
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:
1、如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。(值传递)
2、如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。(引用传递)