[转] Java se 7新特性研究(二)
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp82
今天主要研究Java se 7中异常处理的新功能.从今天开始正在将jdk7的说法改为java se 7跟oracle官网的一致
一、新增了try-with-resource 异常声明
在JDK7中只要实现了AutoCloseable或Closeable接口的类或接口,都可以使用try-with-resource来实现异常处理和资源关闭。下面做一下
JDK7以前:
static String readFirstLingFromFile(String path) throws IOException{
BufferedReader br=null;
try{
br=new BufferedReader(new FileReader(path));
return br.readLine();
}catch(IOException e){
e.printStackTrace();
}finally{
if(br!=null)
br.close();
}
return null;
}
JDK7 及以后版本:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
通过以上对比我们可以发现具有以下优点:
1、代码更精练。在Java se 7以前版都有finally块,如果使用一些框架可能会将finally块交由框架处理,如spring。在jdk7及后的版本,只要资源类实现了AutoCloseable或Closeable程序在执行宛try块后会自动close所使用的资源无论br.readLine()是否抛出异常。我估计针对jdk7像spring这些框架也会做出一些比较大的调整。
2、代码更完全。在出现资源泻漏的程序中,很多情况是开发人员没有或没有正确地关闭资源导致的。JDK7后采用try-with-resource的方式,则可以将资源关闭这种与业务实现没有很大直接关系的工作交给JVM完成。省去了部分开发中可能出现的代码风险。
异常抛出顺序。在Java se 7中的try-with-resource机制中异常的抛出顺序与Java se 7以前的版本有一点不一样。
JDK7以前如果rd.readLine()与rd.close()(在finally块中)都抛出异常则只会抛出finally块中的异常,不会抛出rd.readLine();中的异常。这样经常会导致得到的异常信息不是调用程序想要得到的。
JDK7及以后版本中如果采用try-with-resource机制,如果在try-with-resource声明中抛出异(可能是文件无法打或都文件无法关闭)同时rd.readLine();也势出异常,则只会势出rd.readLine()的异常。
try-with-resource可以声明多个资源。下面的例子是在一个zip文件中检索文件名并将检索后的文件名存入一个txt文件中:
public static void writeToFileZipFileContents(String zipFileName, String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset = java.nio.charset.Charset.forName("US-ASCII");
java.nio.file.Path outputFilePath = java.nio.file.Paths.get(outputFileName);
// Open zip file and create output file with try-with-resources statement
try (
java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}
上面的例子,无论正常执行还是有异常抛出,zf和writer都会被执行close()方法。不过需要注意的是在JVM里调用的顺序是与声明的顺序相反。在JVM里调用的顺序为:
writer.close();
zf.close();
所在在使用时一定要注意。
声明资源时要分析好资源关闭顺序。
JDK7及后的版本的JDBC也支持try-with-resource.如下示例:
public static void viewTable(Connection con) throws SQLException {
String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";
try (Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + ", " + supplierID + ", " + price +
", " + sales + ", " + total);
}
} catch (SQLException e) {
JDBCTutorialUtilities.printSQLException(e);
}
}
在try-with-resource中也可以有catch与finally块。只是catch与finally块是在处理完try-with-resource后才会执行。
二、catch多种异常并抛出新的异常
1、catch多种异常抛出一种异常
在JDK7以前大家会经常处理类似下面的代码:
try{
.........
}catch (IOException ex) {
logger.log(ex);
throw new SpecialException();
catch (SQLException ex) {
logger.log(ex);
throw new SpecialException();
}
这处理导致代码非常的难看,和许多重复的代码。JDK7后,大家可以这样处理:
try{
.........
}catch (IOException | SQLException ex) {
logger.log(ex);
throw new SpecialException();
}
注:在上面例子中的ex是隐式的final不可以在catch块中改变ex.
2、Rethrowing Exceptions with More Inclusive Type Checking
在Java se 7以前的版本。在方法声明中声明抛出的异常如果在方法体内没有抛出是不允许的。如下示例:
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;
}
}
上面这种代码其实很多开发人员都不喜欢,有的可能会提出一些改进方法,但无法做到非常精准的方法异常声明。下面看一下Java se 7的做法:
public void rethrowException(String exceptionName)
throws Exception, FirstException, SecondException {
try {
// ...
}
catch (Exception e) {
throw e;
}
}
异常处理这一块,Java se7改进了许多,开发人员需要认真的学习和试验。
今天先谈到这里。接下来将谈一下下划线在数字表示中的应用和泛型的改进。
[转] Java se 7新特性研究(二)的更多相关文章
- Java SE 6 新特性: Java DB 和 JDBC 4.0
http://www.ibm.com/developerworks/cn/java/j-lo-jse65/index.html 长久以来,由于大量(甚至几乎所有)的 Java 应用都依赖于数据库,如何 ...
- Java SE 6 新特性: 对脚本语言的支持
2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马).跟 Tiger(Java SE 5)相比,Musta ...
- Java SE 6 新特性: HTTP 增强--转
概述 Java 语言从诞生的那天起,就非常注重网络编程方面的应用.随着互联网应用的飞速发展,Java 的基础类库也不断地对网络相关的 API 进行加强和扩展.在 Java SE 6 当中,围绕着 HT ...
- Java SE 6 新特性: 编译器 API
新 API 功能简介 JDK 6 提供了在运行时调用编译器的 API,后面我们将假设把此 API 应用在 JSP 技术中.在传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤: ...
- DynamicMBean(Java SE 6 新特性: JMX 与系统管理)
Dynamic MBean 是一种在运行时定义其管理接口的 MBean.例如,配置 MBean 可以通过解析 XML 文件来确定它所公开的属性名称和类型. 任何实现 DynamicMBean 接口的类 ...
- [转]Java se 7 最新特性研究(一)
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp81 从2006到现在等待了多年的jdk7终于发布了.这里将对它的一些 ...
- java 1.8新特性(二) 关于 function 接口的使用
需求1:从user集合中 找出age=15的用户 传统方法 就不说了 举例明一下 java1.8 使用Predicate接口解决该需求: @FunctionalInterface public in ...
- Java SE 14 新增特性
Java SE 14 新增特性 作者:Grey 原文地址:Java SE 14 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- Java SE 15 新增特性
Java SE 15 新增特性 作者:Grey 原文地址:Java SE 15 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
随机推荐
- log4g 使用教程
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录.在apache网站:jakarta.apache.org/log4j 可以免费下载到Log ...
- 利用dbutils工具实现数据的增删查改操作(dbutis入门)
一.前期准备 1.安装数据库(如:mysql5.5) 2.安装Eclipse(如:3.4) 3.下载数据库驱动包 4.下载dbutis工具包 5.在Eclipse创建名为 dbutils 的工程并在工 ...
- NYOJ--1058--dfs--部分和问题
/* Name: NYOJ--1058--部分和问题 Author: shen_渊 Date: 15/04/17 19:27 Description: 简单的DFS,以为马上过的,递归的i+1写错了, ...
- 程序设计入门——C语言 习题汇总
<img width="108" height="40" alt="浙江大学" src="http://imgsize.ph ...
- SqQueue(环状队列(顺序表结构))
template<typename ElemType> class SqQueue { protected: int count; int front,rear; int maxSize; ...
- 序列化之protobuf与avro对比(Java)
最近在做socket通信中用到了关于序列化工具选型的问题,在调研过程中开始趋向于用protobuf,可以省去了编解码的过程.能够实现快速开发,且只需要维护一份协议文件即可. 但是调研过程中发现了pro ...
- python 字符串 string
字符串 string 语法: a = 'hello world!' b = "hello world!" 常用操作: 1.乘法操作是将字符串重复输出2遍 >>> ...
- SecureCRT-转换密钥-Xshell-配置服务-使用xshell登录远程linux服务器
这篇文档不保证正确,仅仅是备份个因为所以,不必当真. SecureCRT和xShell这2个工具功能类似,均可以控制远程服务器模拟并发用户. SecureCRT自带功能可以将私钥转换为xShell可用 ...
- 如何使用python来模拟鼠标点击(将通过实例自动化模拟在360浏览器中自动搜索"python")
一.准备工作: 安装pywin32,后面开发需要pywin32的支持,否则无法完成与windows层面相关的操作. pywin32的具体安装及注意事项: 1.整体开发环境: 基于windows7操作系 ...
- 设计模式之桥接模式(Bridge模式)
我想大家小时候都有用蜡笔画画的经历吧.红红绿绿的蜡笔一大盒,根据想象描绘出格式图样.而毛笔下的国画更是工笔写意,各展风采.而今天我们的故事从蜡笔与毛笔说起. 设想要绘制一幅图画,蓝天.白云.绿树.小鸟 ...