本文涵盖了以下主题:
- 处理多种类型的异常
- 重新抛出使用更宽泛的类型检查的异常
在Java SE 7 以及后续版本中, 一个简单的catch
块可以处理多种类型的异常。这种特性可以减少重复代码以及对于捕获过于宽泛的异常的诱惑。
考虑下面的例子,每个catch
块中都包含重复代码:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
在Java SE 7之前的发行版本中 , 由于变量ex
有着不同的类型,很难创建一个公用方法来消除重复代码。
下面的例子在Java SE 7以及后续版本中是有效的,它消除了重复代码:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
catch
子句指定了语句块能处理的异常类型,每种异常类型由竖线(|
)隔开。
注意: 如果catch
块处理多种异常类型,那么catch
参数隐式的声明为final。
在这个例子中,catch
的参数ex
是final
的,因此在catch
块中你不能给它指定任意的值。
编译一个处理多种异常类型的catch
块产生的字节码比编译多个catch
块但每个只能处理一种异常类型产生的字节码要少(因此优越一些)。在由编译器生成的字节码中,一个处理多种异常类型的catch
块没有重复;
字节码没有复制异常处理器。
相比之前的Java SE发行版本,Java SE 7的编译器能够对重新抛出的异常执行更精确的分析。这可以使你在一个方法声明的throws
子句里指定更具体的异常类型。
考虑下面的例子:
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName) throws Exception {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e;
}
}
这个例子的try
块既可以抛出FirstException
也可以抛出SecondException
。假定你想要在rethrowException方法声明中的throws
子句中指定异常类型为这两种类型,在Java SE 7之前的版本中你不能这么做。因为catch
子句的异常参数e是Exception
类型,并且catch块重新抛出这个异常参数
e,所以你只能在rethrowException方法声明中的throws
子句中指定异常类型为
Exception
。
然而在Java SE 7中, 你可以在rethrowException方法声明中的throws
子句中指定异常类型为
FirstException
和SecondException
。Java
SE 7编译器可以探测到由throw e
语句抛出的异常必须来自于try
块,
并且try
块抛出的异常只能是FirstException
和SecondException
。即使catch
子句的异常参数e的类型是Exception
,编译器也可以探测到它是FirstException
还是SecondException
的实例:
public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
// ...
}
catch (Exception e) {
throw e;
}
}
如果catch
块中的catch
参数被指定给另一个值,那么这种分析失效。然而,如果的catch
参数被指定给另一个值,
你必须在方法声明的throws
子句中指定异常类型为Exception
。
具体说来,在Java SE 7及后续版本中, 当你在一个catch
子句中声明一个或多个异常类型并且重新抛出由这个catch
块处理的异常,编译器会验证重新抛出的异常类型是否满足以下条件:
try
块可以抛出它。
- 先前的
catch
块没有办法处理它。
- 它是
catch
子句其中一个异常参数的子类或者超类。
Java SE 7编译器允许你在rethrowException
方法声明中的throws
子句指定异常类型FirstException
和SecondException
。因为你可以重新抛出一个是throws
中声明的任意类型的超类的异常。
在Java SE 7之前的版本中,你抛出的异常不能是 catch
子句其中一个异常参数的一个超类。Java
SE 7之前版本中,编译器在throw e
语句这里会产生"unreported exceptionException
;
must be caught or declared to be thrown"错误。编译器会检查抛出的异常类型是否可指定给rethrowException
方法声明的throws
子句中声明的任意类型。然而,catch参数e的类型是Exception
,
它是FirstException
和SecondException的
一个超类,而不是一个子类。
本文翻译自Oracle官方文档http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html,如有不正确的地方,敬请指正,谢谢!
分享到:
相关推荐
java虚拟机规范 Java SE7 java虚拟机规范 Java SE7 java虚拟机规范 Java SE7
java虚拟机规范,高清PDF版本,含有目录结构:第一章:引言; 第二章:java虚拟结构(运行时区域内存:寄存器,java虚拟机栈,java堆,方法去,运行时常量池,本地方法栈); 第三章:为java虚拟机编译; 第四章:...
Java SE7 语言规范手册,来自:http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
Java SE7 API中文文档-类库查询!Java SE7 API中文文档-类库查询!Java SE7 API中文文档-类库查询!Java SE7 API中文文档-类库查询!Java SE7 API中文文档-类库查询!Java SE7 API中文文档-类库查询!
于想了解 Java 虚拟机 的程序员来说,《Java 虚拟机规范》是必须阅读的,对于想深入了解 Java 语言细节的程序员, 阅读《Java 虚拟机规范》也有极大好处
OCP java SE7 Programmer II Certification Guide
虚拟机 Java 1.7 SE7
Java Virtual Machine Specification Java SE 7 中文版 Java Virtual Machine Specification Java SE 7 中文版 Java虚拟机规范SE7
介绍了Java虚拟机的规范,可以挑选自己需要的章节进行读取。
虚拟机方面的权威著作 java虚拟机规范SE7,包含中文版和英文版
OCA Java SE7 Programmer I认证学习指南(Exam 1Z0-803).rar
同时,基于最新Java SE 7平台,它详细介绍了Java SE 7中新加入的lnvokeDynamic指令和方法句柄机制,给出了在Java SE 6期间引入的类型检查检验器的原理证明。本书还介绍了Java SE 5中对class文件格式的扩展变动,例如...
Java SE 7 API文档。jdk7 API文档。Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向...
https://pan.baidu.com/s/1kO1Ng7HW_3I2Us8SpBoesw Java虚拟机规范
se7en管理模板,基于Bootstrap3实现,好资源要多分享
新版做了全面更新,体现了Java SE7的变化,并将对Java SE 7新特性的完整描述融入对Java基本概念的精辟阐述中。 Java核心技术卷II:高级特性(第9版英文版)(上、下册)专为做实际项目的程序员编写,是一本真实可信、...
Se7en是一个基于基于Bootstrap3的,仿ios7风格的,完全响应式的后台框架,她内置了5套简单的皮肤模板,她还加入了近20个国外优秀的开源项目,并可简单组合与拆卸,她采用了全新的设计,最新的技术和最佳的行业实践结果,并...
《Java虚拟机规范 7》是一份完整的描述Java虚拟机是如何设计的规范文档。这份文档对于任何一个希望实现Java虚拟机的编译器作者,或者希望实现一个与规范相兼容的Java虚拟机的程序员来说都是必不可少的。