It enables the use of try-with-resources which is a new feature from Java 7.
Old-school:
InputStream is = null;
try {
is = ...;
// do stuff with is...
} catch (IOException e) {
// handle exception
} finally {
if (is != null) {
try {
is.close();
} catch (IOException innerE) {
// Handle exception
}
}
}
New-school:
try (InputStream is = ...) {
// do stuff with is...
} catch (IOException e) {
// handle exception
}
AutoCloseable objects can be opened in the try-block (within the ()) and will be automatically closed instead of using the finally block as in the code example above.
From the Oracle docs:
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
So, this means that all objects that are AutoCloseable can be used this way which means that e.g. ResultSet and other resources can be used in the try-with-resources way. IMO, this simplifies the coding and readability.
However, readability is not the killer argument for why to use the new way. I believe that it is the simple fact that the resources are automatically closed. When used prior to Java 7 it was possible to forget to do null-checks or to close the underlying resource - try-with-resources is simply less error-prone.
But, with that said. It is not required to use try-with-resources, it is still possible to use it the old-school way even though I would not recommend it due (since it is both verbose and error-prone).
Answer from wassgren on Stack OverflowVideos
It enables the use of try-with-resources which is a new feature from Java 7.
Old-school:
InputStream is = null;
try {
is = ...;
// do stuff with is...
} catch (IOException e) {
// handle exception
} finally {
if (is != null) {
try {
is.close();
} catch (IOException innerE) {
// Handle exception
}
}
}
New-school:
try (InputStream is = ...) {
// do stuff with is...
} catch (IOException e) {
// handle exception
}
AutoCloseable objects can be opened in the try-block (within the ()) and will be automatically closed instead of using the finally block as in the code example above.
From the Oracle docs:
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
So, this means that all objects that are AutoCloseable can be used this way which means that e.g. ResultSet and other resources can be used in the try-with-resources way. IMO, this simplifies the coding and readability.
However, readability is not the killer argument for why to use the new way. I believe that it is the simple fact that the resources are automatically closed. When used prior to Java 7 it was possible to forget to do null-checks or to close the underlying resource - try-with-resources is simply less error-prone.
But, with that said. It is not required to use try-with-resources, it is still possible to use it the old-school way even though I would not recommend it due (since it is both verbose and error-prone).
Read the documentation of the try-with-resources feature introduced in Java 7.
The
try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implementsjava.lang.AutoCloseable, which includes all objects which implementjava.io.Closeable, can be used as a resource.
And the Javadoc of AutoCloseable#close():
Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the
try-with-resources statement.
This means you can create your own subtypes of AutoCloseable resources and use them in this statement.
The point of try-with-resources is that:
- The opening of the
Closeableresource is done in thetrystatement - The use of the resource is inside the
trystatement's block close()is called for you automatically.
So your suggested code:
try(Closeable c = map.remove(key)) {}
... doesn't satisfy the point of try-with-resource, since you're not using the resource inside the block. Presumably your Closeable is already open before this statement.
I'm guessing that you have some code whereby a bunch of resources are opened, work is done, then they are all closed by working through the map.
This is OK, and sometimes unavoidable. But it's cleaner, where possible, to have open() and close() in the same method, with the close() in a finally block, so that you can see at a glance that every open() has a corresponding close() and you can be sure that the close() is always called.
MyCloseable c = MyCloseable.open(...);
try{
// do stuff with c;
} finally {
try {
c.close();
} catch (IOException e) {
// ...
}
}
Once you've achieved that, try-with-resources just makes things neater:
try(MyCloseable c = MyCloseable.open(...)) {
// do stuff with c;
}
If your requirements mean you can't get open and close into the same methods, then just stick with an explicit close() and ignore the warning.
I would just ignore this warning, If you are managing close operation on your own, then just call close(). Empty try-with-resource looks weird.
Consider to extend Map so close operation will be performed automatically on remove:
public class CloseableMap<K,V extends Closeable> extends HashMap<K,V> {
@Override
public R remove(K key) {
V resource = super.remove(key);
if (resource != null) {
resource.close();
}
return resource;
}
}