java中finally与return_Java中finally与return的执行顺序解析(代码示例)

本篇文章给大家带来的内容是关于Java中finally与return的执行顺序解析(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

都知道,finally的执行特点

1、不管有木有出现异常,finally块中代码都会执行;

2、当try和catch中有return时,finally仍然会执行。

那么问题来了,执行顺序是怎么样的呢?

一个简单的测试类及反编译后的字节码:public class Test {

publicstatic void main(String[] args) {

System.out.println(test());

}

publicstatic int test() {

try{

System.out.println("Codesin try block.");

return0;

}catch (Exception e) {

System.out.println("Codesin catch block.");

return100;

}finally {

System.err.println("Codesin finally block.");

}

}

}

/*

public static int test();

Code:

0: getstatic #2 // Fieldjava/lang/System.out:Ljava/io/PrintStream;

3: ldc #5 // String Codes in try block.

5: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

8: iconst_0

9: istore_0

10: getstatic #7 // Field java/lang/System.err:Ljava/io/PrintStream;

13: ldc #8 // String Codes in finallyblock.

15: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

18: iload_0

19: ireturn

20: astore_0

21: getstatic #2 // Fieldjava/lang/System.out:Ljava/io/PrintStream;

24: ldc #10 // String Codes in catchblock.

26: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

29: bipush 100

31: istore_1

32: getstatic #7 // Fieldjava/lang/System.err:Ljava/io/PrintStream;

35: ldc #8 // String Codes in finallyblock.

37: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

40: iload_1

41: ireturn

42: astore_2

43: getstatic #7 // Fieldjava/lang/System.err:Ljava/io/PrintStream;

46: ldc #8 // String Codes in finallyblock.

48: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

51: aload_2

52: athrow

*/

可以将我们编写的代码和编译后的字节码做一下对比:

ba849cac8e7ef4b3be06ea547ea5c4ce.png

发现虚拟机为我们做了好多事,它将finally语句块插到try,catch与return语句之间了。这也就是为什么无论异常与否,返回与否,finally都会执行的原因。既然,finally都会执行,那么在finally中return什么就是什么。既然finally前面所有return都是无效的,return还有什么意义呢,所以,实际中finally块是不允许返回的。eclipse编译器会提示warning:finallyblock does not complete normally。

几种情形的测试代码

try{ return; }catch(){} finally{} return;

测试代码:

1.基本数据类型public static int test1(){

int a = 10;

try{

a = 20;

return a;

}catch(Exception e){

//other codes.

}finally{

a += 5;

//other codes.

}

return a;

}//最终返回值为20

2.引用数据类型改变引用对象的值public static StringBuffer test2(){

StringBuffer sb = new StringBuffer("abc");

try{

return sb;

}catch(Exception e){

//other codes.

}finally{

sb.append("DEF");

//other codes.

}

return sb;

}//最终返回中内容为abcDEFpublic static StringBuffer test3(){

StringBuffer sb = new StringBuffer("abc");

try{

return sb;

}catch(Exception e){

//other codes.

}finally{

sb = new StringBuffer("DEF");

//other codes.

}

return sb;

}//最终返回值中的内容为abc

在此种情形的测试中可以发现,在finally之前若有return语句,finally对返回变量无论做什么修改,变量本身是不会再变的,比如为基本类型的变量重新赋值,或是为引用类型的变量重新指定引用都是不会记录到返回值中的。但是finally中的语句会执行,那么在finally中对引用类型的变量指向的对象内容是可以修改的,且修改有效。此种情形可以这样理解,遇到return语句,虚拟机为return的值盖了一套房子,房子能随便拆吗?不能。但是房子里面的人是可以变的。基本数据类型和引用类型的变量本身就是房子,引用类型变量指向的对象中的内容就是房子中的人。

有这样一个小测试:public static int test(int num){

int a = 10;

try{

return a;

}catch(ArithmeticException e){

a = 20;

return a;

}finally{

a = 30;

return a;

}

}

1.1 try 块中没有异常时返回值是多少?

1.2 try块中有ArithmeticException异常时返回值是多少?

1.3 try块中有其他异常时返回值是多少?

答案:全部是30.原因是在执行完try块中return之前的代码后,jvm在return之间插入了finally块中的代码,finally块中含有return,那么就直接返回了。

相关推荐:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值