问题
I was reading this link for try-with-resources
and it says:
The close method of the
Closeable
interface throws exceptions of typeIOException
while the close method of theAutoCloseable
interface throws exceptions of typeException
.
But why? The close method of AutoCloseable
could have also thrown IOException
is there any example that support that close method of AutoCloseable
must throw exceptions of type Exception
回答1:
The AutoClosable
interface is located in java.lang
and is intended to be applied to any resource that needs to be closed 'automatically' (try-with-resources). The AutoClosable
must not be an io releated resource. So the interface can not make any assumption of a concrete exception.
On the other hand Closable
is located in java.io
and extends AutoClosable
, because a Closable
is an AutoClosable
for io resources. Therefore it declares that IOException
s can be thrown on close.
For example... a java.sql.Connection
is an AutoClosable
because it's close method throws SQLException
and a SQLException
is not an IOException
. Think about in memory DBs and it makes sense that closing an sql connection must not throw an IOException
.
EDIT
answered one more doubt i.e. why AutoClosable is kept under java.lang package. Thanks.
I think it is located in java.lang
because try-with-resources was introduced as a language feature in Java 1.7. Thus java.lang
回答2:
Closeable
extends AutoCloseable
, but there could be other particular interfaces that extend this interface. E.g.:
public interface MyCloseable extends AutoCloseable {
void close() throws RuntimeException;
}
They wanted to have an interface that can be used in many cases, and this is why they decided to use Exception
because it also works for other types of exceptions.
回答3:
Further to being able to throw some other types of exceptions than IOException
one beautiful and common use case can be easily overseen:
One can override the interface to have no throws
declaration at all, thus permitting try
being written without explicit exception handling.
In our code we have an interface Searcher
declared in the following way
public interface Searcher<V> extends AutoCloseable {
Stream<V> search();
@Override
void close();
}
This permits the following use of Searcher
instances:
try (Searcher<Datatype> dataTypeSearcher = new DataTypeSearcher(query)) {
return dataTypeSearcher.search();
}
// without any catch statements
If no throws
declaration was present on AutoCloseable
, the above would be the only usage as it would not be possible to override the AutoCloseable
interface throwing an exception not declared on the parent. The way it is currently done, both options are possible.
来源:https://stackoverflow.com/questions/25959779/why-close-method-of-java-lang-autocloseable-throws-exception-but-close-method-o