成员变量可以从外部访问,但它的声明类是用Java进行垃圾收集的吗?

时间:2013-03-16 04:52:20

标签: java garbage-collection

我对java成员变量及其在可达方面的声明类感到困惑。 让我们说,

  1. TestP类具有TestC类型成员变量c1。
  2. 主类引用了TestP p以及对p.c1的另一个引用; (makeP()
  3. 但删除了p1引用(clearP())后,
  4. p1是垃圾收集的,即使p1.c1可以访问。

    如果c1覆盖某些方法(或者甚至只是打开和关闭括号) p1不是垃圾收集的。我想这是因为c1使用了一些TestP区域...... 但是会有一些明确的解释。

    public class Main {
        TestP p;
        TestC c;
        void makeP { p = new TestP(); c = p.c1; }
        void clearP { p = null; }
    }
    
    public class TestP {
        public TestC c1;
    
        public TestP() {
            c1 = new TestC(); // TestP will be garbage-collected.
            // c1 = new TestC() {}; // TestP will not be garbage-collected.
        }
        ...
    }
    
    public class TestC {
        public TestC() {}
    }
    

1 个答案:

答案 0 :(得分:1)

TestP的实例只有在没有引用的情况下才可以进行垃圾回收。匿名内部类的实例 - 或任何内部类 - 具有隐藏成员,该成员是对其封闭实例的引用;即,用

创建的对象
c1 = new TestC() {};

包含对TestP对象的引用,该对象在其构造函数中执行了此语句。换句话说,c1指向实际看起来像这样的类的实例:

class TestP$1 extends Test {
    private TestP $outer;

    TestP$1(TestP outer) {
        this.$outer = $outer;
    }
}

构造函数参数和成员变量被编译器隐藏,但它们就在那里。

在这种情况下,Test的匿名子类的实例将阻止收集TestP的实例。