2

An object has a copy of all the class members(except the static ones), so does an object has a copy of an inner class also?

Below is my code:

    package com.example;

        
    class outerClass{
        
         class innnerClass{
            
            }
    }


    public class A{

      public void main(String[] args){
        outerClass obj1 = new outerClass();

        outerClass.innerClass obj2 = obj1.new innerClass();
      }
    }

My doubt is that the obj2 is an instance of the "innerClass which is a member of outerClass" or an instance of the "innerClass which is a member of obj1 object" ?

2 Answers2

3

When you look at something like the tutorial, you may find a sentence like

When a number of objects are created from the same class blueprint, they each have their own distinct copies of instance variables.

Note that it say variables, not members. But even that is an oversimplification. It actually means, objects can have different values for the instance variables. The definitions of the variables, including annotations and their values, are invariant and copying them to the objects would lead to pointless identical copies.

Likewise, the declarations of methods, including their code, are invariant, hence, there would be no point in copying them around. But the effective behavior of methods operating on instances may be different due to the fact that they are potentially operating on different values.

The same applies to the inner classes. Their definitions are invariant and there’s no need to copy them. But a non-static inner class instance is associated with an outer instance which may have different field values, potentially leading to different behavior of the inner class’ methods.

In your example, there are no instance fields in the outer class and no methods in the inner class depending on the outer object’s state, so it makes no difference which outer instance you use to instantiate the inner class object (except for some minor impact on garbage collection).

Things change when you add state to the outer instance and dependent behavior to the inner:

public class Outer {
    boolean even;
  
    Outer(boolean even) {
      this.even = even;
    }
  
    class Inner {
        @Override
        public String toString() {
          return even? "Even": "Odd";
        }
    }
  
    public static void main(String[] args) {
        Inner i1 = new Outer(true).new Inner();
        Inner i2 = new Outer(false).new Inner();
  
        System.out.println(i1);
        System.out.println(i2);
    }
}

Here, the two Inner instances exhibit different behavior due to the outer object used for their creation. Still, it doesn’t mean that the class definition is copied.

Starting with JDK 16, you will be able to add static members to inner classes. At this point, it becomes important that inner classes are not copied per outer instance, in other words, the static members of inner classes exist exactly one time in the runtime, just like static members of top level or nested static classes.

E.g. we will be able to change the example to

public class Outer {
    boolean even;
  
    Outer(boolean even) {
      this.even = even;
    }
  
    class Inner {
        static {
            System.out.println("Inner initialized");
        }
        @Override
        public String toString() {
          return even? "Even": "Odd";
        }
    }
  
    public static void main(String[] args) {
        Inner i1 = new Outer(true).new Inner();
        Inner i2 = new Outer(false).new Inner();
  
        System.out.println(i1);
        System.out.println(i2);
    }
}

This will work with JDK 16 and newer and print “Inner initialized” exactly once, not twice.

Holger
  • 285,553
  • 42
  • 434
  • 765
0

Yes. Each instance an outer class will possess its own copy of a non-static inner class.

We know this because each instance of a given class will receive its own copy of all non-static members of that class, as stated by the documentation:

When a number of objects are created from the same class blueprint, they each have their own distinct copies of instance variables.

Since a non-static inner class is in fact an instance member of that class, a unique copy of it will be made each time a new instance of its outer class is created. In other words, a non-static inner class is copied just like a non-static method or field.

Furthermore, you cannot declare any static members within a non-static inner class (as explained in this StackOverflow answer), which makes sense considering that a non-static inner class cannot exist without an instance of its outer class. Since a unique copy of a non-static inner class is created for every instance of its outer class, it cannot contain any static members.

HomeworkHopper
  • 300
  • 1
  • 12
  • 1
    I suggest to read the cited text again, carefully. Note that it does not say “members”. Further, note [this answer](https://stackoverflow.com/a/65147661/2711488) to the linked question. – Holger Mar 09 '21 at 11:48
  • @Holger You’re correct. I’m not sure why I assumed it said “members”... clearly I didn’t proofread my answer very well. In any case your answer is far more accurate than mine. – HomeworkHopper Mar 09 '21 at 12:33