Take the 2-minute tour ×

I'm confused about java member variable and its declaring class in reachable-respect. Let's say,

  1. TestP class has TestC type member variable c1.
  2. main class has reference to TestP p and also another reference to p.c1; (makeP())
  3. but after p1 reference is removed(clearP()),

p1 is garbage-collected even p1.c1 is reachable.

Intesting thing is, if c1 overrides some methods(or even just open&close brackets) p1 is not garbage-collected. I guess it is because c1 uses some TestP area... but some clear explanation will be appreciated.

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() {}
share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

The instance of TestP can be garbage collected only if there are no references to it. An instance of an anonymous inner class -- or any inner class -- has a hidden member that is a reference to its enclosing instance; i.e., the object created with

c1 = new TestC() {};

contains a reference to the TestP object in whose constructor this statement was executed. In other words, c1 points to an instance of a class that actually looks something like this:

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

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

The constructor argument and member variable are hidden by the compiler, but they're there.

Under those circumstances, the instance of an anonymous subclass of Test will prevent the instance of TestP from being collected.

share|improve this answer
I didn't know about that inner class has hidden reference. It's clear now. Thank you for quick answer. –  NoraBora Mar 16 '13 at 5:00
add comment

Your Answer


