Java 在没有新对象实例的情况下使用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 {

通常,我经常看到try with resources用于分配一个新对象实例,该实例的
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()){}
。。。