JDK1.7新特性(2):异常和可变长参数处理
时间:2022-05-04
本文章向大家介绍JDK1.7新特性(2):异常和可变长参数处理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
异常
jdk1.7对try--catch--finally的异常处理模式进行了增强,下面我们依次来看增强的方面。
1. 为了防止异常覆盖,给Throwable类增加了addSuppressed方法,可以将一个异常信息追加到另一个异常信息之后:
1 /**
2 * 这是第一种防止前面异常被覆盖的方法,通过在finally块中判断前面是否有异常抛出
3 * 如果有则最终抛出的异常为原来的异常,没有则最终抛出的异常为finally块中的异常。
4 * 此时只能抛出一种异常信息。
5 * @param fileName
6 */
7 private void readFile(String fileName) {
8 FileInputStream input = null;
9 IOException readException = null;
10 try {
11 input = new FileInputStream(fileName);
12 } catch (IOException ex) {
13 readException = ex;
14 } finally {
15 if (input != null) {
16 try {
17 input.close();
18 } catch (IOException e) {
19 // 如果前面没有出现异常,则说明整个异常是此处产生的
20 if (readException == null) {
21 readException = e;
22 }
23 }
24 }
25
26 if (readException != null) {
27 throw new RuntimeException(readException);
28 }
29 }
30 }
31
32 /**
33 * 这是第二种防止异常被覆盖的方法,利用jdk7的新特性。通过在finally块的异常捕获代码中判断前面是否抛出异常,如果抛出异常
34 * 则将finally块中抛出的异常追加在前面的异常信息之后。这样同时可以抛出两种异常信息类型。
35 * @param fileName
36 */
37 private void readFile2(String fileName) {
38 FileInputStream input = null;
39 IOException readException = null;
40 try {
41 input = new FileInputStream(fileName);
42 } catch (FileNotFoundException e) {
43 readException = e;
44 } finally {
45 if (input != null) {
46 try {
47 input.close();
48 } catch (IOException e) {
49 // 如果前面抛出的异常不为空,这里将finally块中的异常信息添加到原异常信息后面
50 if (readException != null) {
51 readException.addSuppressed(e);
52 } else {
53 readException = e;
54 }
55 }
56 }
57 if (readException != null) {
58 throw new RuntimeException(readException);
59 }
60 }
61 }
2. catch块增强,可以同时捕获多个异常,来进行统一的处理:
1 /**
2 * 这里测试jdk7的新特性,一个catch语句中可以捕获多种异常,以 | 分割。
3 */
4 private void catchMore() {
5 // 在jdk1.7新特性这本书中说一个catch块中可以同时捕获属于父子关系的异常(只要子在前父在后,同分开的catch块中的顺序),但实际上在jdk1.8中时不允许的。
6 try {
7 int a = Integer.valueOf("aaa");
8 throw new IOException();
9 }
10 /*
11 会报NumberFormatException已经被捕获
12 catch (NumberFormatException | RuntimeException | IOException e) {
13
14 }*/ catch (NumberFormatException | IOException e) {
15
16 } catch (RuntimeException e) {
17 }
18 }
3. throw语句增强,异常在第二次抛出之后,仍然能够准确的知道最原始的异常类型:
1 /**
2 * jdk1.7之后,即使异常被重新抛出,编译器也知道原始异常类型,而不会被再抛出的异常类型所干扰。
3 * 如果在jdk1.6或者之前的版本,第二个catch只能是ExceptionA,因为原始的ExceptionASub2被抹去了。
4 */
5 private void testRecatch() {
6 try {
7 throw new ExceptionASub2();
8 } catch (ExceptionA e) {
9 try {
10 throw e;
11 } catch (ExceptionASub2 e2) { // 如果是catch (ExceptionASub1 e2) 那么会报编译错误,因为编译器知道原始异常是ExceptionASub2
12
13 }
14 }
15 }
16
17 class ExceptionA extends Exception {}
18 class ExceptionASub1 extends ExceptionA {}
19 class ExceptionASub2 extends ExceptionA {}
4. try语句增强,try块可以进行资源管理:
1 /**
2 * jdk1.7之后,对try块进行了增强,使其中声明的资源总是可以正确的被释放,而不需要多余的finally块来单独处理。
3 * 这有点像python的 with open("a.txt") as file 语句一样。
4 * 需要注意的是,此时资源必须实现AutoCloseable接口,实际上jdk1.7中通过
5 * public interface Closeable extends AutoCloseable,将Closeable继承于AutoCloseable接口。
6 * 如果我们要自己实现资源的关闭,只需直接实现AutoCloseable接口即可。
7 */
8 private void tryWithResource() {
9 String fileName = "a.txt";
10 try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
11
12 } catch (FileNotFoundException e) {
13
14 } catch (IOException e) {
15
16 }
17 }
变长参数
jdk1.7在变长参数和范型结合使用的时候,增加了一个@SafeVarargs。通过该注解来告诉编译器参数类型的安全性,以此来解决每次调用都出现编译警告的问题。
1 /**
2 * 在jdk1.7之前,需要使用@SuppressWarnings("unchecked")注解来给每一个调用该方法的地方取消警告
3 * 。这是因为变长参数的实际值时通过数组来传递的,而数组中传递的时不可具化的范型对象,自身存在类型安全问题,所以编译器
4 * 会给出警告。这在调用java.utils.Arrays.asList方法和java.util.Collections.addAll方法中也会遇到。
5 * jdk1.7中提供了在该方法声明的地方加上@SafeVarargs注解。来表示该方法在与范型结合使用的时候不会出现类型安全问题。
6 * 此时再调用该方法,编译器不会给出警告信息。
7 * 不过需要注意的是,该方法必须声明为static或者final方法,否则会出现编译错误。
8 */
9 @SafeVarargs
10 public static<T> T useVarargs(T... args) {
11 return args.length > 0 ? args[0] : null;
12 }
- Eureka中RetryableClientQuarantineRefreshPercentage参数探秘
- Edgware.RC1中ZuulFallbackProvider的改进
- JPA的多表复杂查询:详细篇
- 尝试使用Memcached遇到的狗血问题
- Enumerable#Zip 实现一下
- 更新自己,不要影响其他人
- 【译】Spring官方教程:Spring Boot整合消息中间件RabbitMQ
- [实录]解决Migrator.Net 小bug
- Jenkins Pipeline插件十大最佳实践!
- Spring Cloud Hystrix的请求合并
- JQuery JCshare 0.1 分享插件
- Java中的即时编译(Just-in-time compilation)
- 无尽的忙碌换来幸福的日子
- 消费者驱动的微服务契约测试套件:Spring Cloud Contract
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- jmeter在linux系统下运行及本地内存调优的方法详解
- Android实现录音功能实现实例(MediaRecorder)
- Linux下9种优秀的代码比对工具推荐小结
- Android开发实现在Wifi下获取本地IP地址的方法
- Android基于Glide v4.x的图片加载进度监听
- Android如何通过scheme跳转界面
- Android EditText实现输入金额类型详解
- ubuntu20.04中文输入法安装步骤
- 如何利用Android Studio将moudle变成jar示例详解
- Android自带的四种线程池使用总结
- CentOS8.1搭建Gitlab服务器详细教程
- Android开发之图片旋转功能实现方法【基于Matrix】
- Android编程简单实现拨号器功能的方法
- win10 + Ubuntu20.04 LTS双系统引导界面美化
- Android开发从相册中选取照片的示例代码