java异常捕获分析
java异常捕获分析
思考问题:
调用下面的方法分别会返和输出回什么?
package com.itdragon.controller;
import org.junit.Test;
public class TestMain {
public int test1() {
int a=0;
try {
a=1/0;
} catch (Exception e) {
System.out.println("test1:err");
a=100;
return a;
}finally {
System.out.println("test1:fin");
a=200;
return a;
}
}
public int test2() {
int a=0;
try {
a=1/0;
} catch (Exception e) {
System.out.println("test2:err");
a=100;
return a;
}finally {
System.out.println("test2:fin");
a=200;
}
return a;
}
@Test
public void tests(){
System.out.println("test1:"+test1());
System.out.println();
System.out.println("test2:"+test2());
}
}
众所周知,java捕获到异常时,先执行catch 代码块,如果有finally代码块,那么无论最后有没有异常都会执行finally代码块。
对于test1都好理解,最后在finally中返回,值为200.
但是对于test2就有点难以理解,认为应该返回200,但是却返回了100.
对于上述两个方法简化,在做叙述:
public int test1() {
int a=0;
try {
a=1/0;
} catch (Exception e) {
a=100;
return a;
}finally {
a=200;
return a;
}
}
public int test2() {
int a=0;
try {
a=1/0;
} catch (Exception e) {
a=100;
return a;
}finally {
a=200;
}
return a;
}
反编译出的字节码如下:
test1
public int test1();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=5, args_size=1
0: iconst_0 //将int型0推送至栈顶
1: istore_1 //将栈顶int型数值存入第二个本地变量
2: iconst_1 //将int型1推送至栈顶
3: iconst_0 //将int型0推送至栈顶
4: idiv //将栈顶两int型数值相除并将结果压入栈顶
5: istore_1 //将栈顶int型数值存入第二个本地变量
6: sipush 200 //将一个短整型常量值(-32768~32767)推送至栈顶
9: istore_1 //将栈顶int型数值存入第二个本地变量
10: iload_1 //将第二个int型本地变量推送至栈顶
11: ireturn //从当前方法返回int
12: astore_2 //将栈顶引用型数值存入第三个本地变量
13: bipush 100 //将单字节的常量值(-128~127)推送至栈顶
15: istore_1 //将栈顶int型数值存入第二个本地变量
16: iload_1 //将第二个int型本地变量推送至栈顶
17: istore_3 //将栈顶int型数值存入第四个本地变量
18: sipush 200 //将一个短整型常量值(-32768~32767)推送至栈顶
21: istore_1 //将栈顶int型数值存入第二个本地变量
22: iload_1 //将第二个int型本地变量推送至栈顶
23: ireturn //从当前方法返回int
24: astore 4 //将栈顶引用型数值存入指定本地变量
26: sipush 200 //将一个短整型常量值(-32768~32767)推送至栈顶
29: istore_1 //将栈顶int型数值存入第二个本地变量
30: iload_1 //将第二个int型本地变量推送至栈顶
31: ireturn //从当前方法返回int
Exception table:
from to target type
2 6 12 Class java/lang/Exception
2 6 24 any
12 18 24 any
24 26 24 any
test2:
public int test1();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=5, args_size=1
0: iconst_0 //将int型0推送至栈顶
1: istore_1 //将栈顶int型数值存入第二个本地变量
2: iconst_1 //将int型1推送至栈顶
3: iconst_0 //将int型0推送至栈顶
4: idiv //将栈顶两int型数值相除并将结果压入栈顶
5: istore_1 //将栈顶int型数值存入第二个本地变量
6: sipush 200 //将一个短整型常量值(-32768~32767)推送至栈顶
9: istore_1 //将栈顶int型数值存入第二个本地变量
10: goto 34 //无条件跳转
13: astore_2 ////将栈顶引用型数值存入第三个本地变量
14: bipush 100 //将单字节的常量值(-128~127)推送至栈顶
16: istore_1 // 将栈顶int型数值存入第二个本地变量
17: iload_1 //将第二个int型本地变量推送至栈顶
18: istore_3 //将栈顶int型数值存入第四个本地变量
19: sipush 200 // 将一个短整型常量值(-32768~32767)推送至栈顶
22: istore_1 //将栈顶int型数值存入第二个本地变量
23: iload_3 //将第四个int型本地变量推送至栈顶
24: ireturn // 从当前方法返回int
25: astore 4 //将栈顶引用型数值存入指定本地变量
27: sipush 200 //将一个短整型常量值(-32768~32767)推送至栈顶
30: istore_1 //将栈顶int型数值存入第二个本地变量
31: aload 4 //将指定的引用类型本地变量推送至栈顶
33: athrow //将栈顶的异常抛出
34: iload_1 //将第二个int型本地变量推送至栈顶
35: ireturn // 从当前方法返回int
Exception table:
from to target type
2 6 13 Class java/lang/Exception
2 6 25 any
13 19 25 any
25 27 25 any
可能对于不是太了解字节码的同学来说不好理解。
但是从中我的理解是:当有finally块存在的时候,虚拟机执行完catch块中的代码时不会立即返回,而是把return语句给屏蔽了,将catch中的代码执行完以、变量在局部变量表中保存好以后,继续执行finally块中的代码,如果finally块中有返回语句,则直接返回,否则,虚拟机去取在catch块中保存的局部变量,放入栈顶,返回。
评论区
请写下您的评论...
猜你喜欢
java基础
2346
Java异常体系java异常体系继承图ThrowableThrowable类是所有异常的父类,常见的子类有两个Error、Exception。ErrorError类就是程序运行时候抛出的最严重级别的
blog
Java内存区域与内存溢出异常
java基础
3751
当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里[1],字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理
ofc
Java内存区域与内存溢出异常
official
878
《深入理解java虚拟机》[TOC]一、运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随
ofc
中断和异常
official
917
《操作系统》中断机制的诞生早期的计算机各程序只能串行执行,执行完这一个才能执行下一个,所以系统资源利用率低。为了解决上述问题,人们发明了操作系统(作为计算机的管理者),引入中断机制,实现了多道程序并发执行本质:发生中断就意味着需要操作系统介入,开展管理工作。中断的概念和作用1.当中断发生时,CPU立即进入核心态2.当中断发生后,当前运行的进程暂停运行,并由操作系统内核对中断进行处理3.对于不同的中
blog
springmvc统一返回异常信息
spring/springmvc
2342
springmvc统一返回异常信息当服务器代码为: @RequestMapping("/res") publicMyAjaxResultres(@RequestParam(name
blog
java集合之HashMap理解和分析
java基础
1377
1.HashMap的构造函数1.publicHashMap()publicHashMap(){this.loadFactor=DEFAULT_LOAD_FACTOR;//allotherfieldsdefaulted}构造一个空的HashMap,初始容量为16,负载因子为0.75,负载因子和它的作用将会在下方解释。2.publicHashMap(intinitialCapacity)publicH
java虚拟机(jvm)
4453
Java对象的创建Java是一门面向对象的编程语言,在Java程序运行过程中无时无刻都有对象被创建出来。在语言层面上,创建对象(例如克隆、反序列化)通常仅仅是一个new关键字而已,而在虚拟机中,对象
blog
jvm内存模型分析(1)
java虚拟机(jvm)
3026
jvm内存模型分析(1)Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域jvm包括三大子系统:类加载子系统,运行时数据区(内存结构),执行引擎详细图示
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
2024-08
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。