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