概述
我有一个A类:
public class A {
private B b = new B() { public void method() { do something } };
public B getB() { return b; }
}
public interface B { void method(); }
实例b具有其外部类的实例的隐式引用(可以由此引用).现在另一个对象通过getter方法获取对此b的引用.由于引用,该b不能被垃圾收集.
有没有办法获得允许封闭A实例的垃圾收集的可能性,可能是通过重置匿名内部类中的显式引用?
解决方法:
技术上可行:
public class HasInner {
public static interface Foo {}
private static T release(T instance, Object ref) {
try {
Class> type = instance.getClass();
for (Field field : type.getFields()) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
if (field.get(instance) == ref) {
field.set(instance, null);
}
}
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
return instance;
}
public Foo makeFoo() {
return release(new Foo() {}, this);
}
public static void main(String[] args) {
new HasInner().makeFoo();
}
}
匿名类的javap检查:
Compiled from "HasInner.java"
final class HasInner$1 extends java.lang.Object implements HasInner$
Foo{
final HasInner this$0;
HasInner$1(HasInner);
}
该实现不依赖于字段名称为$0,因为我怀疑这是一个编译器实现细节.
潜在问题领域:
>安全管理员可以禁止反射代码.
>我不认为Java平台确切地定义了内部类型如何引用外部.也就是说,它是一个编译器实现细节,如果是愚蠢的,在字段中有一个中间包装器是合法的 – 在其他字段存在的情况下,消除引用的歧义可能是不可能的.
简而言之,我永远不会这样做.
如果这是一个问题,请使用私有静态内部类:
public class A {
private static class BImpl implements B {
@Override public void method() {
}
}
private final B b = new BImpl();
public B getB() { return b; }
}
标签:java,inner-classes,garbage-collection
来源: https://codeday.me/bug/20190607/1191824.html
最后
以上就是谨慎钻石为你收集整理的java匿名对象 回收_java – 允许在其他地方引用匿名内部类实例时对类进行垃圾回收?...的全部内容,希望文章能够帮你解决java匿名对象 回收_java – 允许在其他地方引用匿名内部类实例时对类进行垃圾回收?...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复