我对java成员变量及其在reachable-方面的声明类感到困惑。
比方说


TestP类具有TestC类型成员变量c1。
主类引用了TestP p,还引用了p.c1; (makeP()
但是在删除p1引用(clearP())之后,


即使可以访问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() {}
}

最佳答案

TestP的实例只有在没有引用的情况下才能被垃圾回收。匿名内部类(或任何内部类)的实例具有一个隐藏成员,该成员对其封闭实例进行引用。即使用

c1 = new TestC() {};


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

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

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


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

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

关于java - 成员变量可以从外部访问,但是其声明类是用Java垃圾收集的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15445728/

10-09 16:38