Saturday, 14 December 2013

Try with resources.

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.  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.
InputStream is = null;
try {
 is = url.openStream();
 OutputStream out = new FileOutputStream(file);
 try {
 byte[] buf = new byte[4096];
 int len;
 while ((len = is.read(buf)) >= 0)
 out.write(buf, 0, len);
 } catch (IOException iox) {
 } finally {
 try {
 out.close();
 } catch (IOException closeOutx) {
 }
 }
} catch (FileNotFoundException fnfx) {
} catch (IOException openx) {
} finally {
 try {
 if (is != null) is.close();
 } catch (IOException closeInx) {
 }
}
InputStream is = null;
try {
 is = url.openStream();
 OutputStream out = new FileOutputStream(file);
 try {
 byte[] buf = new byte[4096];
 int len;
 while ((len = is.read(buf)) >= 0)
 out.write(buf, 0, len);
 } catch (IOException iox) {
 } finally {
 try {
 out.close();
 } catch (IOException closeOutx) {
 }
 }
} catch (FileNotFoundException fnfx) {
} catch (IOException openx) {
} finally {
 try {
 if (is != null) is.close();
 } catch (IOException closeInx) {
 }
}
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);
}
}

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")) ) {
...
}

No comments:

Post a Comment