Thật không may, trí tưởng tượng của tôi đã trở nên hoang dã khi bạn hỏi câu hỏi này. Tôi không biết nếu giải pháp này được coi là thanh lịch hơn. Tuy nhiên, các lớp này rất đơn giản và có thể tái sử dụng dễ dàng nên bạn có thể tìm cách sử dụng chúng nếu không vừa ý. Bạn sẽ thấy mọi thứ kết hợp lại với nhau vào cuối ...
public class BinaryCloseable implements Closeable {
private Closeable first;
private Closeable last;
public BinaryCloseable(Closeable first, Closeable last) {
this.first = first;
this.last = last;
}
@Override
public void close() throws IOException {
try {
first.close();
} finally {
last.close();
}
}
}
BinaryCloseable
được sử dụng bởi CompositeCloseable
:
public class CompositeCloseable implements Closeable {
private Closeable target;
public CompositeCloseable(Closeable... closeables) {
target = new Closeable() { public void close(){} };
for (Closeable closeable : closeables) {
target = new BinaryCloseable(target, closeable);
}
}
@Override
public void close() throws IOException {
target.close();
}
}
ResultSetCloser
đóng ResultSet
đối tượng:
public class ResultSetCloser implements Closeable {
private ResultSet resultSet;
public ResultSetCloser(ResultSet resultSet) {
this.resultSet = resultSet;
}
@Override
public void close() throws IOException {
try {
resultSet.close();
} catch (SQLException e) {
throw new IOException("Exception encountered while closing result set", e);
}
}
}
PreparedStatementCloser
đóng PreparedStatement
đối tượng:
public class PreparedStatementCloser implements Closeable {
private PreparedStatement preparedStatement;
public PreparedStatementCloser(PreparedStatement preparedStatement) {
this.preparedStatement = preparedStatement;
}
@Override
public void close() throws IOException {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new IOException("Exception encountered while closing prepared statement", e);
}
}
}
ConnectionCloser
đóng Connection
đối tượng:
public class ConnectionCloser implements Closeable {
private Connection connection;
public ConnectionCloser(Connection connection) {
this.connection = connection;
}
@Override
public void close() throws IOException {
try {
connection.close();
} catch (SQLException e) {
throw new IOException("Exception encountered while closing connection", e);
}
}
}
Bây giờ chúng tôi cấu trúc lại InputStream
ban đầu của bạn ý tưởng thành:
public class ClosingInputStream extends InputStream {
private InputStream stream;
private Closeable closer;
public ClosingInputStream(InputStream stream, Closeable closer) {
this.stream = stream;
this.closer = closer;
}
// The other InputStream methods...
@Override
public void close() throws IOException {
closer.close();
}
}
Cuối cùng, tất cả kết hợp lại với nhau dưới dạng:
new ClosingInputStream(
stream,
new CompositeCloseable(
stream,
new ResultSetCloser(resultSet),
new PreparedStatementCloser(statement),
new ConnectionCloser(connection)
)
);
Khi ClosingInputStream
này của close()
phương thức được gọi, đây thực sự là những gì sẽ xảy ra (với việc xử lý ngoại lệ bị bỏ qua vì lợi ích của sự rõ ràng):
public void close() {
try {
try {
try {
try {
// This is empty due to the first line in `CompositeCloseable`'s constructor
} finally {
stream.close();
}
} finally {
resultSet.close();
}
} finally {
preparedStatement.close();
}
} finally {
connection.close();
}
}
Giờ đây, bạn có thể tự do đóng bao nhiêu Closeable
các đối tượng như bạn muốn.