今天在论坛看到一篇关于异常处理的文章,异常处理机制详解开头就搬出了这样一个例子:

public class TestException {
public TestException() {
} boolean testEx() throws Exception {
boolean ret = true;
try {
ret = testEx1();
} catch (Exception e) {
System.out.println("testEx, catch exception");
ret = false;
throw e;
} finally {
System.out.println("testEx, finally; return value=" + ret);
return ret;
}
} boolean testEx1() throws Exception {
boolean ret = true;
try {
ret = testEx2();
if (!ret) {
return false;
}
System.out.println("testEx1, at the end of try");
return ret;
} catch (Exception e) {
System.out.println("testEx1, catch exception");
ret = false;
throw e;
} finally {
System.out.println("testEx1, finally; return value=" + ret);
return ret;
}
} boolean testEx2() throws Exception {
boolean ret = true;
try {
int b = 12;
int c;
for (int i = 2; i >= -2; i--) {
c = b / i;
System.out.println("i=" + i);
}
return true;
} catch (Exception e) {
System.out.println("testEx2, catch exception");
ret = false;
throw e;
}
finally {
System.out.println("testEx2, finally; return value=" + ret);
return ret;
}
} public static void main(String[] args) {
TestException testException1 = new TestException();
try {
testException1.testEx();
} catch (Exception e) {
e.printStackTrace();
}
}
}

它打印的结果:

i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, catch exception
testEx1, finally; return value=false
testEx, finally; return value=false

很多人诧异的一点是testEx2明明抛出了异常throw e,为什么外层异常处理器没有其作用,文章并没有谈及,不知道是作者谦虚还是留给大家去探索。本文不聊一些基础性的东西,因为网上这种文章太多,我没必要重复去说,我只想分析一下为什么是这样的一个打印结果。

package Test;  

public class TestException {
public TestException() {
} boolean testEx() throws Exception {
boolean ret = true;
try {
ret = testEx1();
} catch (Exception e) {
// 同理不会捕捉异常
System.out.println("testEx, catch exception");
ret = false;
throw e;
} finally {
System.out.println("testEx, finally; return value=" + ret);
return ret;
}
} boolean testEx1() throws Exception {
boolean ret = true;
try {
ret = testEx2(); // 内部异常已被finally 的return 屏蔽
if (!ret) {
return false;
}
System.out.println("testEx1, at the end of try");
return ret;
} catch (Exception e) {
// 异常处理器无效,此处代码跳过直接finally
System.out.println("testEx1, catch exception");
ret = false;
throw e;
} finally {
System.out.println("testEx1, finally; return value=" + ret);
return ret; // 同理如果此处的return 被拿掉则不会屏蔽掉throw e ,关键就看当前函数的最后一条语句是return 还是 throw
}
} boolean testEx2() throws Exception {
boolean ret = true;
try {
int b = 12;
int c;
for (int i = 2; i >= -2; i--) {
c = b / i;
// 1.首先打印2递减 打印i=2 , i=1
System.out.println("i=" + i); // 当i=0 运行时异常抛出
}
return true;
} catch (Exception e) {
// 2. Exception 包含除Error外的所有运行时异常,能够处理抛出异常 打印 testEx2, catch exception
System.out.println("testEx2, catch exception");
ret = false;
// 3. 程序要抛出异常但是有finally子句,需要执行
throw e;
} finally {
// 4. 打印
System.out.println("testEx2, finally; return value=" + ret);
// 5. 此处return JVM认定此函数能够正常响应 屏蔽throw e子句 ,如果此处不是return 子句,外层catch能捕获异常,因为JVM会认定此函数没有return , 返回异常
return ret;
}
} public static void main(String[] args) {
TestException testException1 = new TestException();
try {
testException1.testEx();
} catch (Exception e) {
e.printStackTrace();
}
}
}

JVM根据try - catch -> finally语句的执行顺序,看最后返回的是throw还是return来判断是正常返回还是抛出异常。

Java内部抛出异常外部不能catch问题分析的更多相关文章

  1. JAVA安装过程中出现的“javac不是内部或外部指令”的解决方法

    近来重新安装了JAVA,安装过程中出现问题,网上找到解决办法,汇总发布. 解决流程: 1.确定自己的环境变量设置没问题,没有出现遗漏 : . 等情况 (具体环境变量设置百度) 2.环境变量设置后 ,d ...

  2. java编译正常javac出错不是内部或外部命令

    javac不是内部或外部命令 安装jdk版本jdk-8u111-windows-x64(jdk1.8.0_111) 配置环境: JAVA_HOME D:\xiazai\Java\jdk1.8.0_11 ...

  3. 1. webservice在输入命令的时候wsimport的时候会出现如下错误: wsimport不是内部或者外部命令。 2. javac不是内部或者外部命令 3 java 就可以显示配置成功。

    问题: webservice在输入命令的时候wsimport的时候会出现如下错误: wsimport不是内部或者外部命令. javac不是内部或者外部命令 3 java 就可以显示配置成功. 网上搜了 ...

  4. Java基础知识强化50:运行javac 报告javac不是内部或外部命令(已解决)

    1. 问题:运行javac 报告javac不是内部或外部命令,但是运行java.java-version正常 ? 看看下面三个环境变量是否设置正确: (1)环境变量  JAVA_HOME 设置JAVA ...

  5. Tomcat学习笔记 - 错误日志 - Tomcat安装版安装后第二次启动后闪退(转)-- javac不是内部或外部命令 -- 配置java环境教程

    如果安装成功并且安装完成第一次启动是成功的,第二次就闪退的话,原因之一是没有配置java的环境.在网上找的配制方法有很多错误,测试javac命令时候会提示不是内部或外部命令,找到一个正确的教程.如下, ...

  6. 关于win10系统1709版本安装JDK出现变量配置正确但仍有“java不是内部或外部命令”的解决办法

    背景:联想拯救者R720笔记本,系统一键还原了,需要重新安装一部分软件,最基本的就是JDK,但今天在安装时遇到了问题,之前安装的1.8版本,没有仔细配置环境变量,这一次安装的是1.7版本的,仔仔细细配 ...

  7. win10配置java环境变量,解决javac不是内部或外部命令等问题

    win10配置java环境变量,解决javac不是内部或外部命令等问题 https://www.cnblogs.com/qianji/p/6402690.html

  8. windows下java环境变量的配置 javac不是内部或外部命令的问题

    安装配置JAVA JDK 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html . 下载你电脑对应的JDK,下 ...

  9. window10下java环境变量的配置 javac不是内部或外部命令的问题

    http://blog.csdn.net/suncold123/article/details/48392135 参考与上面这个博主. 今天在win10下重新配置了一下java环境变量.跟着网上的流程 ...

随机推荐

  1. Wget使用

    http://www.tuicool.com/articles/A7BRny wget / curl 是两个比较方便的测试http功能的命令行工具,大多数情况下,测试http功能主要是查看请求响应 头 ...

  2. 新手前端笔记之--初识css

    css样式表是为了容纳与html文档分离出来的样式属性而产生的,所以她理所当然的包含两个部分:1.样式的表示,使用{属性1:属性值:属性2:属性值:...},2.样式与标签的对应(如何找的对应标签), ...

  3. C# 向DataTable中插入数据或伪造DataTable

    方法一: DataTable  tblDatas = new DataTable("Datas"); DataColumn dc = null; dc = tblDatas.Col ...

  4. C# 中 int、Convert.ToInt32()、int.Parse()的区别

    int适合简单数据类型之间的转换,C#的默认整型是int32(不支持bool型); int.Parse(string sParameter)是个构造函数,参数类型只支持string类型; Conver ...

  5. git还原文件

    http://jingyan.baidu.com/album/e4511cf33479812b855eaf67.html

  6. [MySQL 5.1 体验]MySQL 实例管理器 mysqlmanager 初试

    原贴:http://imysql.cn/node/313 [MySQL 5.1 体验]MySQL 实例管理器 mysqlmanager 初试 周二, 2007/06/19 - 22:10 - yejr ...

  7. Java调用jama实现矩阵运算

    Java调用jama实现矩阵运算 一.jama简介 Jama是一个基本的线性代数java包.包括一个基本的Matrix类和5个矩阵分解类. Matrix类提供了基本的线性代数数值运算的功能,不同的构造 ...

  8. (cocos2d-js游戏)測试你的反应速度----------基本逻辑(上)

    游戏玩法:点击開始游戏.等待一个随机时间.然后背景颜色会变(在t1时刻),这时候你须要点击屏幕(在t2时刻),游戏结束.你的反应时间就是天t2-t1. 游戏逻辑: 游戏逻辑非常easy,如上图所看到的 ...

  9. magento getCarriers 分析

    完整的设置订单追踪信息的时候我们可能会用到它.在后台中他在这里设置: 有的时候我们想要设置自己定义的 carrier 比如 顺丰 申通 圆通 ..等等 我们能够先从 magento api 入手分析 ...

  10. 使用Spring框架的好处

    转自:https://www.cnblogs.com/hoobey/p/6032506.html 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JD ...