Java 在没有新对象实例的情况下使用try-with-resources是否是错误的形式?
通常,我经常看到try with resources用于分配一个新对象实例,该实例的Java 在没有新对象实例的情况下使用try-with-resources是否是错误的形式?,java,try-with-resources,Java,Try With Resources,通常,我经常看到try with resources用于分配一个新对象实例,该实例的close()方法在超出范围时被调用 据我所知,创建一个新对象并不是一项要求,try with resources语法只需要一个局部变量,在超出范围时调用close()。因此,您可以使用它来控制“成对操作”,例如从池中分配某些内容并确保返回 例如,下面的MyHandle显示了当不再需要池实例时如何释放它: // init class MyHandle implements AutoCloseable {
close()
方法在超出范围时被调用
据我所知,创建一个新对象并不是一项要求,try with resources语法只需要一个局部变量,在超出范围时调用close()。因此,您可以使用它来控制“成对操作”,例如从池中分配某些内容并确保返回
例如,下面的MyHandle显示了当不再需要池实例时如何释放它:
// 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...
//初始化
类MyHandle实现自动关闭{
布尔inUse=false;
公共MyHandle分配(){
因纽斯=真;
归还这个;
}
公众假期结束(){
因纽斯=假;
}
}
MyHandle[]池=新的MyHandle[池大小];
for(int i=0;i
这被认为是不好的形式吗
编辑:我想我是在问,是否有更好的替代方案来构建这种逻辑,或者在使用上述方法时是否存在一些重大缺陷。我发现在库中使用它可以创建一个干净的API
编辑2:请忽略代码示例中的问题,我在SO文本框中内联编写了它,以通过某种示例明确我的问题。显然这不是真正的代码!:) try-with-resource语法是一种语法糖化,它允许您确保处理对象,不管处理逻辑是什么。在您的例子中,它将对象返回到池中。像这样使用try-with-resource绝对没有错。它可能不是最常见的用例,但肯定是有效的。在幕后,大多数资源(如文件描述符)都是由操作系统从池中有效分配的,然后在关闭时返回到池中 以这种方式使用try-with-resources是完全有效的
注意:虽然您的代码示例存在严重的线程问题,但我假设为了问题的清晰性,已经删除了必要的线程安全性。我之所以提到它,只是因为人们不应该复制您的代码并在实现中使用它。尝试使用类似的资源没什么错。但在您的情况下,我会担心意外重用已从另一个线程重新打开的关闭句柄 稍微间接一点就可以解决这个问题,返回
myhandlerapper
,而不是直接访问MyHandle
(allocateFromPool将返回myhandleRapper的一个新实例)。不会的解决所有其他线程问题
public class MyHandleWrapper extends MyHandle {
private MyHandle handle;
private boolean closed;
public void close() {
if(!closed){
handle.inUse = false;
}
closed = true;
}
public void read() {
if (closed) {
throw new IllegalStateException("Already closed");
}
handle.read();
}
}
基本上,如果在MyHandleRapper中关闭了句柄,您将保留信息。您可以使用该标志保护对
handle
的任何状态更改访问,如果需要,可以抛出适当的异常。这很好-使用连接池时通常也是这样做的:try(connection c=pool\u或\u datasource.getConnection()){}
。。。