java7新特性之Try-with-resources (TWR)


This change is easy to explain, but it has proved to have hidden subtleties, which

made it much less easy to implement than originally hoped. The basic idea is to allow

a resource (for example, a file or something a bit like one) to be scoped to a block in

such a way that the resource is automatically closed when control exits the block.

This is an important change, for the simple reason that virtually no one gets manual resource closing 100 percent right. Until recently, even the reference how-tos from Sun were wrong. The proposal submitted to Project Coin for this change

includes the astounding claim that two-thirds of the uses of close() in the JDK had

bugs in them!

Fortunately, compilers can be made to produce exactly the sort of pedantic, boilerplate code that humans so often get wrong, and that’s the approach taken by this change.

This is a big help in writing error-free code. To see just how helpful, consider how

you’d write a block of code that reads from a stream coming from a URL (url) and

writes to a file (out) with Java 6. Here’s one possible solution.




How close did you get? The key point here is that when handling external resources,

Murphy’s Law applies—anything can go wrong at any time:

■ The InputStream can fail to open from the URL, to read from it, or to close

properly.

■ The File corresponding to the OutputStream can fail to open, to write to it, or

to close properly.

■ A problem can arise from some combination of more than one factor.

This last possibility is where a lot of the headaches come from—a combination of

exceptions is very difficult to deal with well.

This is the main reason for preferring the new syntax—it’s much less error-prone.

The compiler isn’t susceptible to the mistakes that every developer will make when trying to write this type of code manually.



Let’s look at the Java 7 code for performing the same task as listing 1.3. As before, url

is a URL object that points at the entity you want to download, and file is a File object

where you want to save what you’re downloading. Here’s what this looks like in Java 7.
try (OutputStream out = new FileOutputStream(file);
InputStream is = url.openStream() ) {
byte[] buf = new byte[4096];
int len;
while ((len = is.read(buf)) > 0) {
out.write(buf, 0, len);
}
}

This basic form shows the new syntax for a block with automatic management—the

try with the resource in round brackets. For C# programmers, this is probably a bit

reminiscent of a using clause, and that’s a good conceptual starting point when working with this new feature. The resources are used by the block, and they’re automatically disposed of when you’re done with them.

You still have to be careful with try-with-resources, as there are cases where a

resource might still not be closed.
For example, the following code would not close its

FileInputStream properly if there was an error creating the ObjectInputStream

from the file (someFile.bin).

try ( ObjectInputStream in = new ObjectInputStream(new
FileInputStream("someFile.bin")) ) {
...
}


Let’s assume that the file (someFile.bin) exists, but it might not be an ObjectInput

file, so the file might not open correctly. Therefore, the ObjectInputStream wouldn’t

be constructed and the FileInputStream wouldn’t be closed!

The correct way to ensure that try-with-resources always works for you is to split the

resources into separate variables.

try ( FileInputStream fin = new FileInputStream("someFile.bin");
ObjectInputStream in = new ObjectInputStream(fin) ) {
...
}

One other aspect of TWR is the appearance of enhanced stack traces and suppressed

exceptions. Prior to Java 7, exception information could be swallowed when handling

resources
. This possibility also exists with TWR, so the stack traces have been enhanced

to allow you to see the type information of exceptions that would otherwise be lost.

For example, consider this snippet, in which a null InputStream is returned from

a method:

try(InputStream i = getNullStream()) {
i.available();
}

This will give rise to an enhanced stack trace, in which the suppressed NullPointerException (NPE for short) can be seen:


Exception in thread "main" java.lang.NullPointerException

at wgjd.ch01.ScratchSuprExcep.run(ScratchSuprExcep.java:23)

at wgjd.ch01.ScratchSuprExcep.main(ScratchSuprExcep.java:39)

Suppressed: java.lang.NullPointerException

at wgjd.ch01.ScratchSuprExcep.run(ScratchSuprExcep.java:24)

1 more





We encourage you to use try-with-resources as soon as you’re able, to eliminate unnecessary bugs from your codebase.



TWR and AutoCloseable

Under the hood, the TWR feature is achieved by the introduction of a new interface,

called AutoCloseable, which a class must implement in order to be able to appear

as a resource in the new TWR try clause. Many of the Java 7 platform classes have

been converted to implement AutoCloseable (and it has been made a superinterface of Closeable), but you should be aware that not every aspect of the platform

has yet adopted this new technology. It’s included as part of JDBC 4.1, though.

For your own code, you should definitely use TWR whenever you need to work with

resources. It will help you avoid bugs in your exception handling.


读书笔记:The
Well-Grounded Java Develope


java7新特性之Try-with-resources (TWR)的更多相关文章

  1. java7新特性之Diamond syntax

    java7新特性之Diamond syntax Java 7 also introduces a change that means less typing for you when dealing ...

  2. java7新特性 java8新特性

    Java 7 的7个新特性 Java7语法新特性 JAVA8 十大新特性详解 http://www.jb51.net/article/48304.htm

  3. Java7 新特性 数值文本表示法

    今天和大家分享下 java7中新特性-数值文本表示法 首先,在原来jdk1.6中 如果需要将一个二进制的数值转换成十进制的话,一般情况下都会以下面的代码方式去实现. public static voi ...

  4. java7 新特性 总结版

    Java7语法新特性: 前言,这是大部分的特性,但还有一些没有写进去,比如多核 并行计算的支持加强 fork join 框架:这方面并没有真正写过和了解.也就不写进来了. 1. switch中增加对S ...

  5. Java7新特性

    ① 新增了switch对字符串的支持,也就是说可以在switch之后直接使用字符串来进行判断,语法基本与Java7之前支持的语法一样. ② 对数值字面量的增强支持,首先是可以在源代码中直接使用二进制数 ...

  6. Java7 新特性: try-with-resources

    Try-with-resources是java7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源. 利用Try-Catch-Finally管理资源(旧的代码风格)在ja ...

  7. Java7 新特性 —— java.nio.file 文件操作

    本文部分摘自 On Java 8 自 Java7 开始,Java 终于简化了文件读写的基本操作,新增了 java.nio.file 库,通过与 Java8 新增的 stream 结合可以使得文件操作变 ...

  8. Java7 新特性 switch 可以使用String

    今天和大家分享下 在java7中可以使用String 作为switch 中的参数. 原来在java7之前,switch只能去接收一个 byte.char.short.int 类型 现在在java7中 ...

  9. Java7新特性(一)Coin

    1.语法糖 数字下划线   2.switch语句中的String   3.multicatch   4.final重抛 对比上份代码   5.try-with-resources(TWR) AutoC ...

随机推荐

  1. sh NonUniqueObjectException

    话题引入: 使用hibernate进行更新操作时,首先调用了findById方法获取要修改的对象,此时session没有被关闭,接着重新创建一个对象,将要修改的属性值赋值给这个对象.调用修改方法抛出如 ...

  2. Java SE、Java EE、Java ME 三者区别

    现在一个个来分析 1. Java SE(Java Platform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 ...

  3. 德尔福 XE5 安卓调试

    https://stackoverflow.com/questions/2604727/how-can-i-connect-to-android-with-adb-over-tcp?page=2&am ...

  4. 新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”

    新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”, 其主要原因是文件夹的权限问题,手动将项目文件夹权限更改为可读可写就OK,具体操 ...

  5. pytorch之Tensor与Variable的区别

    首先在变量的操作上:Tensor对象支持在原对象内存区域上修改数据,通过“+=”或者torch.add()方法而Variable不支持在原对象内存区域上修改数据Variable对象可求梯度,并且对Va ...

  6. 邮箱地址自动提示jQuery插件

    // mailAutoComplete.js v1.0 邮箱输入自动提示// 2010-06-18 v2.0 使用CSS class类代替CSS对象,同时增强代码可读性// 2010-06-18 v2 ...

  7. MongoDB的游标操作

    MongoDB的游标操作 制作人:全心全意 游标:查询的返回资源或接口,这个接口可以逐条查询 游标的声明 var cursor = db.collection名.find(); cursor.hasN ...

  8. 转载,Django组件

    知识预览 一 Django的form组件 二 Django的model form组件 三 Django的缓存机制 四 Django的信号 五 Django的序列化 回到顶部 一 Django的form ...

  9. C++ 类 直接定义对象与new对象的区别

    new创建类对象与直接定义的区别 new创建对象的特点 new创建类对象需要指针接收,一处初始化,多处使用 new创建类对象使用完需delete销毁 new创建对象直接使用堆空间,而局部不用new定义 ...

  10. 绑定IP 绑定设备

    首先引别人的组播测试如下 1. 一个udp client可以同时往多个组播地址发送数据,多个udpclient可以同时往一个组播发数据. 2. 本地udp必须监听组播端口,否则收不到数据.3. 一个u ...