我对java成员变量及其在可达方面的声明类感到困惑。 让我们说,
makeP()
)clearP()
)后,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() {}
}
答案 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
的实例。