Java 在使用PantomReferences完成过程中,我会避免使用反射吗?

Java 在使用PantomReferences完成过程中,我会避免使用反射吗?,java,reflection,finalization,phantom-reference,Java,Reflection,Finalization,Phantom Reference,假设我创建了一个实现Closable的类MyClass。因此,在close()方法中,我将释放一些非常重要的资源。因为它是非常重要的资源,所以我创建了某种安全网络(正如有效Java中推荐的)。这是: protected void finalize(){ if (/*user didn't call close() method by himself*/){ close(); } } public class CustomPhantom extends PhantomReference

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

protected void finalize(){
if (/*user didn't call close() method by himself*/){
    close();
}
}
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
}
}
起初我很高兴,但后来我读到finalizer并没有那么酷,还有一个像PhantomReference这样的酷工具。所以我决定将代码改为使用PhantomReference,而不是finalize()方法。我创建了CustomPantom扩展了PhantomReference。这是:

protected void finalize(){
if (/*user didn't call close() method by himself*/){
    close();
}
}
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
}
}
因此,正如我所看到的,获得对对象的引用的唯一方法是使用反射,并从引用类中的referent字段获取if。这是从清理方法调用MyClass.close()的唯一方法吗


另外,我还没有在这里发布所有的代码,但我已经测试过了,一切正常。引用队列由PhantomReferences填充,然后我可以一个接一个地获取它们并调用cleanup方法。但是我看不出如何在不使用反射的情况下解决上述问题。

对于幻影引用,这样的操作是做不到的,甚至反射也帮不上忙。只有在GC已经发生之后,才能在
ReferenceQueue
中获得引用,因此没有更多的对象可以调用
close()


您可以做的一件事——事实上,这是一个好主意——是使用
PhantomReference
抛出一个错误,表示您应该直接调用
close()
。例如,您可以让referent对象引用您的
CustomPhantom
,并调用
CustomPhantom.setCleanedUp(true)
方法。然后,在您的
CustomPhantom
中,如果您在
ReferenceQueue
中,并且该队列尚未清理,则可以显示一条警告。

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


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

谢谢您的回答。我被这个链接弄糊涂了。那家伙说我们可以用反射从幻影中复活这个物体