Java 在使用PantomReferences完成过程中,我会避免使用反射吗?
假设我创建了一个实现Closable的类MyClass。因此,在close()方法中,我将释放一些非常重要的资源。因为它是非常重要的资源,所以我创建了某种安全网络(正如有效Java中推荐的)。这是: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
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将被抛出。谢谢您的回答。我被这个链接弄糊涂了。那家伙说我们可以用反射从幻影中复活这个物体