1700448903
1700448904
对于这段代码,有两个问题:main方法中的doStuff方法的返回值是什么?doStuff方法永远都不会抛出异常吗?
1700448905
1700448906
答案是:doStuff(-1)的值是-1,doStuff(100)的值也是-1,调用doStuff方法永远都不会抛出异常,有这么神奇?原因就是我们在finally代码块中加入了return语句,而这会导致出现以下两个问题:
1700448907
1700448908
(1)覆盖了try代码块中的return返回值
1700448909
1700448910
当执行doStuff(-1)时,doStuff方法产生了DataFormatException异常,catch块在捕捉此异常后直接抛出,之后代码执行到finally代码块,就会重置返回值,结果就是-1了,也就是出现了先返回,再执行finally,再重置返回值的情况。
1700448911
1700448912
有读者可能会扩展思考了:是不是可以定义一个变量,在finally中修改后再return呢?代码如下:
1700448913
1700448914
public static int doStuff(){
1700448915
1700448916
int a=1;
1700448917
1700448918
try{
1700448919
1700448920
return a;
1700448921
1700448922
}catch(Exception e){
1700448923
1700448924
}finally{
1700448925
1700448926
//重新修改一下返回值
1700448927
1700448928
a=-1;
1700448929
1700448930
}
1700448931
1700448932
return 0;
1700448933
1700448934
}
1700448935
1700448936
该方法的返回值永远是1,而不会是-1或0(为什么不会执行到“return 0”呢?原因是finally执行完毕后该方法已经有返回值了,后续代码就不会再执行了),这都是源于异常代码块的处理方式,在代码中加上try代码块就标志着运行时会有一个Throwable线程监视着该方法的运行,若出现异常,则交由异常逻辑处理。
1700448937
1700448938
我们知道方法是在栈内存中运行的,并且会按照“先进后出”的原则执行,main方法调用了doStuff方法,则main方法在下层,doStuff在上层,当doStuff方法执行完“return a”时,此方法的返回值已经确定是in类型1(a变量的值,注意基本类型都是值拷贝,而不是引用),此后finally代码块再修改a的值已经与doStuff返回者没有任何关系了,因此该方法永远都会返回1。
1700448939
1700448940
继续追问:那是不是可以在finally代码块中修改引用类型的属性以达到修改返回值的效果呢?代码如下:
1700448941
1700448942
public static Person doStuff(){
1700448943
1700448944
Person person=new Person();
1700448945
1700448946
person.setName(“张三”);
1700448947
1700448948
try{
1700448949
1700448950
return person;
1700448951
1700448952
}catch(Exception e){
[
上一页 ]
[ :1.700448903e+09 ]
[
下一页 ]