Member Inner Class in Java


A non-static class that is declared inside a class but outside the method is known as member inner class or regular inner class. It can be declared as public, default, private, and protected. The member inner class in Java can be declared like this.
  class Outer
   {
   // A member inner class named Inner.
      class Inner  
       {
         .....
        }
   }
When you compile the class like this javac Outer.java, the compiler will generate two separate dot class files like this Outer.class for outer class and Outer$Inner.class for the inner class. This is because inner is not direct class. It is present in somewhere inside outer class. Therefore, the compiler will generate a dot class file like Outer$Inner.class. The $ symbol represents the inner class.

When you run the above code, you will get "Error: Main method not found in class innerclass.A. This is because the outer class does not contain any main() method.

Let's take some more example programs to clear the concepts.
Program source code 1: 
    package innerClass; public class A { // A member inner class named B. class B { } // Inner class end. public static void main(String[] args){ System.out.println("Outer class main method"); } }
    Output: Outer class main method
In this program, we have declared the main() method inside the outer class. When you run this code, it will print the Outer class main method. But what will happen when you declare the main() method inside the inner class, not outer class? Let's see the code.

Program source code 2:
    package innerClass; public class A { // A member inner class named B. class B { public static void main(String[] args){ System.out.println("Outer class main method"); } } }
When you will try to compile this code, it will not compile because inside the inner class, we cannot declare any static member including main() method.
Key points to remember:
➲ A member inner class cannot have a static declaration. It means that we cannot have the main method in the inner class because it is static. 

How to instantiate Member Inner class in Java


An object or instance of a member inner class always exists within an object of its outer class. The new operator is used to create the object of member inner class with slightly different syntax. the general form of syntax to create an object of the member inner class is as follows:
    OuterClassReference.new MemberInnerClassConstructor();
Here, OuterClassReference is the reference of the outer class followed by a dot which is followed by the new operator. Consider the above first example and follow the two steps.

Step 1: To create an object of Inner member inner class, you must have to create first an object of its outer class. 
     Outer o=new Outer(); // (1)
Now, you need to use the new operator on the 'o' object reference variable to create the object of a member inner class.
    Outer.Inner i=o.new Inner(); // (2)
Where i is an object reference variable to store the member inner class object.
      Inner() is a constructor name that is the same as the simple class name for member inner class. 

When you combine the above two lines of code, you can write the following new statement.
   Outer.Inner i=new Outer.new Inner(); // One line of code.
Suppose you are calling any method like m1() using object reference variable i. 
     i.m1(); // Calling m1 method. // (3)
On combining (1), (2), and (3), you will get the following statement.
     new Outer().new Inner().m1();

Now consider the following class declaration with inner classes nested at multiple levels.
    public class A {
       public class B {
           public class C {
             public class D {
                   ..............
             }
           }
        }
   }
How will you create an object of class D in the above lines of code?
To create an object of D, you must have an object of C. To create an object of C, you must have an object of B. Similarly, to create an object of B, you must have an object of A. Therefore, you must start by creating an object of A to create an object of D.
Key points to remember:
To create an object of a member inner class, you first create an object of its immediate enclosing i.e outer class.

The following snippet of code is given below to create an object of D:  
     A   a=new  A();
       A.B   b=a.new  B();
         A.B.C   c=b.new  C();
            A.B.C.D   d=c.new  D();

Let's start with a different example program to understand all concepts.

Accessing Inner class code from the static area of outer class


You can access the members of an inner class from the static area of the outer class. Let's see an example program.
Porgram source code 3:
    package innerClass; public class A { // A member inner class named B. class B { public void m1(){ System.out.println("Inner class method"); } } public static void main(String[] args){ // Static area of the outer class. System.out.println("Outer class main method"); // Create an instance of class A. A a=new A(); // Create an instance of class B and call the method m1() from the static area of the outer class using reference variable i. A.B b=a.new B(); b.m1(); } }
    Output: Outer class main method Inner class method

Accessing Inner class code from instance area of outer class


In this program, we will call the members of the inner class from the instance area of outer class.
Program source code 5:
    package innerClass; public class A { // A member inner class named B. class B { public void m1(){ System.out.println("Inner class method"); } } // An instance area of outer class. void m2(){ // Instance method of outer class. System.out.println("Outer class instance method"); // To call the method m1 of an inner class B, here create directly an object of inner class in the instance area. B b=new B(); b.m1(); } public static void main(String[] args){ // Create an instance of class A. A a=new A(); a.m2(); } }
    Output: Outer class instance method Inner class method
In the above program, we have created an object of A and called m1() method using reference variable a. The control of execution will be immediately transferred to the m2() method that is an instanced area of the outer class A's method m2(). Here, we have created an object of B directly and called the method m2() using reference variable b.
Member inner class in java

Accessing Inner class code from outside of outer class


Program source code 6:
    package innerClass; public class A { // A member inner class named B. class B { public void m1(){ System.out.println("Inner class method"); } } // An instance area of outer class. void m2(){ System.out.println("Outer class instance method"); } } package innerClass; public class Test { public static void main(String[] args) { A a=new A(); A.B b=a.new B(); a.m2(); b.m1(); } }
    Output: Outer class instance method Inner class method

Accessing Instance variable & Static variable of the Outer class from an Inner class


Program source code 7:
    package innerClass; public class MyOuter { // Declare instance variables and static variable. int p=10; protected int q=20; private int r=30; static int s=40; // Regular Inner class starts here. class MyInner { public void display(){ System.out.println("Value of p: " +p); System.out.println("Value of q: " +q); System.out.println("Value of r: " +r); System.out.println("Value of s: " +s); } } public static void main(String[] args) { new MyOuter().new MyInner().display(); } }
    Output: Value of p: 10 Value of q: 20 Value of r: 30 Value of s: 40
As you can see in the above example programs that we can directly access both static and non-static variables including private of the outer class. 


Key points to remember:
An inner class cannot have the static declaration but it does mean that we cannot access the static members of the outer class inside the inner class. Declaration and accessing both are different things. We can directly access both static and non-static variable such as public, default, protected, and private variables of the outer class inside the inner class.
Let's take another example program.
Program source code 8:
    package innerClass; public class MyOuter3 { private int a=20; class MyInner3 { private int b=30; private void showValue(){ System.out.println("Value of a: " +a); } } public void displayValue(){ MyInner3 i=new MyInner3(); System.out.println("Value of b: " +i.b); i.showValue(); } public static void main(String[] args) { MyOuter3 o=new MyOuter3(); o.displayValue(); } }
    Output: Value of b: 30 Value of a: 20
1. From the above program, it is clear that we can directly access the private instance variable and method of the outer class inside the inner class area.
2. By creating an object of the inner class, we can also access the private members (variables and methods) of an inner class inside the enclosing class instance area.

Key points to remember:
An inner class can directly access all of the variables and methods including private of its outer class but the reverse is not true. The enclosing class does not have access to the members of an inner class directly. That is without creating an object of the inner class within the outer class's instance area, you cannot access any members of an inner class.

Accessing Member Inner class having the same instance variable name as its Outer class


Program source code 9:
    package innerClass; public class MyOuter2 { // Declare an instance variable of the outer class and initialize the value 20. int x=20; // A regular member inner class start here. class MyInner2 { // An instance variable of member inner class int x=30; public void showValue(){ // A local variable of member inner class. int x=40; System.out.println(x); // It will print the value 40 of local variable x. System.out.println(this.x); // It will print the value 30 of instance variable of member inner class because here this refers to the current inner class object. System.out.println(MyOuter2.this.x); // It will print the value 20 of instance variable of outer class because here this refers to current outer class object. } } public static void main(String[] args) { MyOuter2 mo=new MyOuter2(); MyOuter2.MyInner2 mi=mo.new MyInner2(); mi.showValue(); } }
    Output: 40 30 20
Key points to remember:
1. Within an inner class, this.x always refers to the current inner class object. 
2. MyOuter2.this.x refers to the current outer class object. Using this syntax, you can call the current outer class object x value.

Accessing Nesting of Inner class from Static area of Outer class


Program source code 10:
    package innerClass; public class P { String name="Ricky"; // Nesting of inner class starts here. class Q { private String name="Deep"; class R { String name="John"; public void msg(){ System.out.println("Welcome you."); System.out.println(P.this.name); System.out.println(this.name); //Here, you cannot access the variable of class R using this keyword. } } } public static void main(String[] args) { P p=new P(); P.Q q=p.new Q(); P.Q.R r=q.new R(); r.msg(); System.out.println(q.name); }
    Output: Welcome you. Ricky John Deep
Final words 
Hope that this article has covered almost all the practical example programs related to member inner class in java. We hope that you have enjoyed this article. All the concepts are very important for the technical test and interview.
Thanks for reading!