我尝试使用类成员作为try块中的资源(因为该资源需要在try块后调用close(((:
class Manager {
MyResource m_myResource;
...
void doTraining() {
m_myResource = createMyResource();
try(m_myResource) {
...
}
}
}
但会有人抱怨说m_myResource
不是有效的决赛。为什么?我认为m_myResource
在初始化后没有改变。无论如何,不知道如何解决这个问题。我能想到的一种方法是:
class Manager {
MyResource m_myResource;
...
void doTraining() {
MyResource newResource = createMyResource();
m_myResource = newResource;
try(m_myResource) {
...
}
}
}
但我不确定将本地资源分配给类成员是否会引起任何问题?
class Manager {
MyResource m_myResource;
...
void doTraining() {
try(MyResource newResource = createMyResource()) {
m_myResource = newResource;
...
}
finally {
m_myResource = null;
}
}
}
因此,当doTraining()
的try()
块中没有正在进行的操作时,字段总是null
。
很明显,doTraining
的这个实现是不可重入的;无论是通过多个线程还是通过递归调用,都不能有对该方法的重叠调用。
如前所述,不建议这样做。但有时,通过操作中使用的所有API层传递资源是不切实际的。这种情况的存在已经被认识到,并且有一个计划的通用解决方案ExtentLocal
。
有了这个,未来的版本将看起来像
class Manager {
final static ExtentLocal<MyResource> MY_RESSOURCE = new ExtentLocal<>();
...
void doTraining() {
try(MyResource newResource = createMyResource()) {
ExtentLocal.where(MY_RESSOURCE, newResource )
.run(() -> {/* code indirectly invoking foo */});
...
}
}
void foo() {
var resource = MY_RESSOURCE.get();
// use resource
}
}
请注意,这不会使传递本地有效资源的实例发生变化。所以这里,doTraining()
是可重入的。
但是,这是在未来的某个地方…