0

假设我创建了一个实现 Closable 的类 MyClass。所以在 close() 方法中,我将释放一些非常重要的资源。好吧,因为它是非常重要的资源,所以我创建了某种安全网络(如 Effective Java 中推荐的那样)。这里是:

protected void finalize(){
if (/*user didn't call close() method by himself*/){
    close();
}
}

一开始我很高兴,但后来我读到终结器并不那么酷,而且有一个像 PhantomReference 这样很酷的工具。所以我决定更改我的代码以使用 PhantomReference 而不是 finalize() 方法。我创建了 CustomPantom 扩展了 PhantomRefernce。这里是:

public class CustomPhantom extends PhantomReference {

//Object cobj;

public CustomPhantom(Object referent, ReferenceQueue q) {
    super(referent, q);
    //this.cobj = referent;   can't save the refference to my object in a class field,
                        // because it will become strongly rechable 
                        //and PhantomReference won't be put to the reference queue  
}

public void cleanup(){
    //here I want to call close method from my object, 
            //but I don't have a reference to my object
}
}

因此,正如我所见,我可以获得对我的对象的引用的唯一方法是使用反射并从 Reference 类中的引用字段中获取 if。这是从清理方法调用 MyClass.close() 的唯一方法吗?

PS我没有在这里发布所有代码,但我测试了它并且一切正常。ReferenceQueue由PhantomReferences填充,然后我可以一一获取并调用清理方法。但是我看不到如何在不使用反射的情况下解决上述问题。

4

2 回答 2

1

你不能用幻像引用做这样的事情,甚至反射也无济于事。您只能ReferenceQueue在 GC 已经发生之后获得引用,因此没有更多对象可以调用close()

你可以做的一件事——事实上是个好主意——是使用PhantomReference来抛出一个错误,说你应该close()直接调用而没有调用。例如,您可能让引用对象引用您的CustomPhantom,并调用一个CustomPhantom.setCleanedUp(true)方法。然后在你的 中CustomPhantom,如果你在 aReferenceQueue并且它没有被清理,你可以显示一个警告。

于 2014-04-07T20:23:15.553 回答
0

由于有接受的答案,我只是添加更多信息。

当使用 Java 反射 API 来检查类PantomReferences时,您不会得到字段引用NoSuchFieldException将被抛出。

于 2018-01-09T05:23:40.433 回答