目录
java的异常捕捉的标准格式是try...catch...finally块,那么我们在与return结合的时候,返回值是如何确定的呢?
1.走try块中的return
public class tryDemo {
public static int show() {
int b = 20;
try {
System.out.println("try语句块");
return b+=80;
/**
* 等价于两个步骤
* b+=80;
* return b;
*/
}catch (Exception e){
System.out.println("catch语句块");
}finally {
System.out.println("finally语句块");
if (b>25){
System.out.println("b>25,b="+b);
}
b=120;
}
return b;
}
public static void main(String args[]) {
System.out.println("最终结果:" + show());
}
}
在try块确定返回值之后,真正return之前,执行了finally块里面的java代码,所以 到达finally块的时候b的值是100,但是b=120这个是无法生效的,因为在try块的时候已经确定了返回的值,无法被finally部分修改。但是如果是引用类型,引用地址无法被修改,但是其成员变量的值是可以更改的。
下面的demo是引用数据类型:
public class tryDemo {
public static RetDto show() {
RetDto retDto = new RetDto();
try {
retDto.age = 2;
System.out.println(retDto);
System.out.println(retDto.age);
return retDto;
}finally{
System.out.println("finally模块被执行");
retDto.age = 3;
retDto = null;
}
}
public static void main(String args[]) {
RetDto show = show();
System.out.println(show);
System.out.println(show.age);
}
}
class RetDto{
String name;
int age;
}
输出结果:
可以确定,在try块的最后一行已经确定了返回的RetDto对象的地址,所以在finally里的最后retDto = null;这一行的代码是无效代码,但是RetDto在堆中的属性值是可以更改的。编译器其实都可以识别,如下:
2.走catch块中的return
public class tryDemo {
public static int show() {
int b = 20;
try {
System.out.println("try语句块");
b=b/0;
return b+=80;
}catch (Exception e){
b+=15;
System.out.println("catch语句块");
return b;
}finally {
System.out.println("finally语句块");
if (b>25){
System.out.println("b>25,b="+b);
}
b+=50;
}
}
public static void main(String args[]) {
System.out.println("最终结果:" + show());
}
}
输出结果:
catch块的道理和try块一致,都是先确定返回值,再走finally,最后才return,可以把return语句从catch拿到方法末尾,这个时候finally里面的b+=50就生效了:
public class tryDemo {
public static int show() {
int b = 20;
try {
System.out.println("try语句块");
b=b/0;
return b+=80;
}catch (Exception e){
b+=15;
System.out.println("catch语句块");
}finally {
System.out.println("finally语句块");
if (b>25){
System.out.println("b>25,b="+b);
}
b+=50;
}
return b;
}
public static void main(String args[]) {
System.out.println("最终结果:" + show());
}
}
输出结果:
3.走finally块中的return
public class tryDemo {
public static int show() {
int b = 20;
try {
System.out.println("try语句块");
return b+=80;
}catch (Exception e){
System.out.println("catch语句块");
}finally {
System.out.println("finally语句块");
if (b>25){
System.out.println("b>25,b="+b);
}
b = 200;
return b;
}
}
public static void main(String args[]) {
System.out.println("最终结果:" + show());
}
}
输出结果:
可以看到,finally块中的return会覆盖try块中的return。
总结:
如果finally块中没有return语句,finally代码片段在try或catch中的return确定返回值之后执行,执行完finally语句之后才真正将返回值return(若返回值是基本数据类型,其值无法被finally里面修改;若返回值是引用类型,其地址值无法被更改,但是其属性还是可以被更改的)。
如果finally中也有return则覆盖try、catch中的return语句直接返回。