Sayangnya, imajinasi saya menjadi liar ketika Anda menanyakan pertanyaan ini. Saya tidak tahu apakah solusi ini dianggap lebih elegan. Namun, kelas-kelas ini sederhana dan mudah digunakan kembali sehingga Anda dapat menemukan kegunaannya jika tidak memuaskan. Anda akan melihat semuanya menyatu di akhir...
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
digunakan oleh 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
tutup ResultSet
objek:
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
tutup PreparedStatement
objek:
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
menutup Connection
objek:
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);
}
}
}
Kami sekarang memfaktorkan ulang InputStream
asli Anda ide menjadi:
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();
}
}
Akhirnya, semuanya menjadi satu:
new ClosingInputStream(
stream,
new CompositeCloseable(
stream,
new ResultSetCloser(resultSet),
new PreparedStatementCloser(statement),
new ConnectionCloser(connection)
)
);
Saat ClosingInputStream
ini close()
metode ini dipanggil, inilah yang terjadi secara efektif (dengan penanganan pengecualian dihilangkan demi kejelasan):
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();
}
}
Anda sekarang bebas untuk menutup sebanyak Closeable
objek sesuka Anda.