0

I have this code :

public class EnclosingClass {
    public int age; 
    public int height ; 
    class Job {
        public String dateBegin ; 
        public int yearsExperience;
        public void displayCompleteProfile() {
            System.out.println(toString()+" age : "+age+" height : "+height);
        }
        @Override
        public String toString() {
            return "Job [dateBegin=" + dateBegin + ", yearsExperience=" + yearsExperience + "]";
        }


    } 

    @Override
    public String toString() {
        return "EnclosingClass [age=" + age + ", height=" + height + "]";
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        EnclosingClass enClass = new EnclosingClass();
        enClass.age = 20; 
        enClass.height = 170;           
        EnclosingClass.Job job1 = enClass.new Job();
        job1.dateBegin = "12/12/2008";
        job1.yearsExperience = 5;

        job1.displayCompleteProfile();
        enClass = null;
        job1.displayCompleteProfile();

    }

}  

and when I execute the code I get this result :

Job [dateBegin=12/12/2008, yearsExperience=5] age : 20 height : 170
Job [dateBegin=12/12/2008, yearsExperience=5] age : 20 height : 170

How come my nested class object job1 still has access to it's enclosing class instance enClass attributes even after I set the object to null?

LuminousNutria
  • 1,883
  • 2
  • 18
  • 44
mounaim
  • 1,132
  • 7
  • 29
  • 56
  • 1
    when you call `enClass = null` you are only changing the reference variable `enClass` not the instance `enClass` points to, more reading https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value – Adam Siemion Jan 19 '19 at 22:41
  • so job1 holds an other reference to enClass instance and all the instances of Job that were created from enClass ? – mounaim Jan 19 '19 at 23:23
  • job1 holds a reference to the EnclosingClass instance (as will each instance of Job). job1 does not know about all other instances of Job. –  Jan 20 '19 at 00:59

1 Answers1

2

When you have a nested class that is not static, all instances of that class will automatically contain an instance of the outer class that contains it.

In this case, even after you set enClass = null, there is still a reference to it held by job1. Because that reference is there, even though you can no longer access it directly, it is not eligible for garbage collection.

Joe C
  • 15,324
  • 8
  • 38
  • 50
  • is it possible somehow to reconstruct the EnclosingClass object from the reference job1 holds ? how to access this reference ? – mounaim Jan 19 '19 at 23:26
  • 2
    The instances of the inner class will contain a *reference* to the instance of the outer class, not the actual instance! Pedantic, perhaps, but that's the same error as in the OP's question: the distinction between an object and a reference. –  Jan 20 '19 at 00:56
  • 2
    @mounaim: there's nothing to "reconstruct". The EnclosingClass object exists until the last reference to it has been removed. It therefore exists as long as any of its nested Jobs exists. The Job can refer to its EnclosingClass as ```EnclosingClass.this``` –  Jan 20 '19 at 01:01