Nói chung tôi luôn thấy tài nguyên thử dùng để phân bổ đối tượng mới dụ có phương thức close()
được gọi khi nó nằm ngoài phạm vi. Theo như tôi có thể nói, việc tạo một đối tượng mới không phải là một yêu cầu và cú pháp try-with-resources chỉ cần một biến cục bộ để gọi close() khi nó nằm ngoài phạm vi. Vì vậy, bạn có thể sử dụng nó để kiểm soát "hoạt động được ghép nối" chẳng hạn như phân bổ thứ gì đó từ một nhóm và đảm bảo nó được trả về.Có đang sử dụng tài nguyên cố gắng mà không có biểu mẫu xấu đối tượng mới không?
Ví dụ, MyHandle dưới đây cho thấy làm thế nào để phát hành một trường hợp gộp khi bạn không còn cần đến nó:
// init
class MyHandle implements AutoCloseable {
boolean inUse = false;
public MyHandle allocate() {
inUse = true;
return this;
}
public void close() {
inUse = false;
}
}
MyHandle[] pool = new MyHandle[POOL_SIZE];
for (int i = 0; i < pool.length; i++) {
pool[i] = new MyHandle(i);
}
// allocate
MyHandle allocateFromPool() {
for (int i = 0; i < pool.length; i++) {
if (!pool[i].inUse)
return pool[i].allocate();
}
throw new Exception("pool depleted");
}
// using resources from the pool
try (MyHandle handle = allocateFromPool()) {
// do something
}
// at this point, inUse==false for that handle...
Đây có phải là coi hình thức xấu?
EDIT: Tôi đoán tôi đang hỏi liệu có lựa chọn thay thế tốt hơn để xây dựng loại logic này hay không, hoặc có một số nhược điểm lớn khi đi theo phương pháp trên. Tôi thấy rằng việc sử dụng điều này trong thư viện làm cho một API sạch sẽ.
EDIT 2: Vui lòng bỏ qua các vấn đề trong ví dụ mã, tôi đã viết nội tuyến trong hộp văn bản SO để làm cho câu hỏi của tôi rõ ràng với một số loại ví dụ. Rõ ràng đó không phải là mã thực! :)
Không sao - đó cũng thường là cách thực hiện khi sử dụng hồ bơi kết nối: 'try (Connection c = pool_or_datasource.getConnection()) {}' ... – assylias