ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java – 允许在其他地方引用匿名内部类实例时对类进行垃圾回收?

2019-06-07 02:58:24  阅读:310  来源: 互联网

标签:java inner-classes garbage-collection


我有一个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> 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有