Types of Inner classes with example - Inner class, static nested class, local and anonymous inner class in java, Difference between static and non-static class


Nested Class?
A class within another class is called nested class.

4 Different type of Nested classes >
  • 1) Inner class / member Inner class
  • 2) static nested class (not a inner class, its just a nested class)
  • 3) Local inner class
  • 4) Anonymous inner class


1) Inner class
  • 1.1) An inner class is a nested class that is not explicitly or implicitly declared static.

  • 1.2) Inner class is also known as
  • member inner class.

  • 1.3) Inner class is considered as instance member variable of outer class.

  • 1.4) Inner class has access to all other member variables of outer class. Inner class can access -
  • instance member variable of outer class
  • instance methods of outer class

  • static member variable of outer class
  • static methods of outer class

  • Outer class reference
  • Inner class reference

  • Inner class is instance specific/ object specific class. It has got access to this reference of outer class.
    • Hence, can access OuterClass instance variable and instance method using OuterClass reference this.

  • 1.5) InnerClass can be declared private, protected, public.
  • 1.6) strictfp modifier can also be used with InnerClass.
  • 1.7) InnerClass can be abstract or final.

  • 1.8) Inner classes cannot declare static initialization blocks
  • 1.9) Inner classes cannot declare member interfaces.
  • 1.10) Inner classes can declare instance initialization blocks
class OuterClass{
   //Inner class
   class InnerClass {
         
          //Inner classes cannot not declare static initialization blocks
          static{} //compilation error
         
          //Inner classes cannot not declare member interfaces.
          interface I{} //compilation error

          //Inner classes can declare instance initialization blocks
          {}
         
          //Inner class constructor
          InnerClass() {}


   }
}


  • 1.11) Inner classes cannot declare static members
  • 1.12) Inner classes can declare constant variables
  • 1.13) Inner classes can inherit static members that are not constant variables.
class A{
  
   //Inner classes can inherit static members that are not constant variables
   static int x = 1;
}
class OuterClass {
   // Inner class
   class InnerClass extends A{
         
          // Inner classes cannot not declare static members
          static int i = 2; // compilation error
         
          //Inner classes can declare constant variables
          static final int j = 3; // Fine
   }
}




Program for instantiating inner class and show what member variable of OuterClass can be accessed in inner class>
package com.ankit;
class OuterClass{
   int i=1; //instanceVariable
   void m(){} //instanceMethod
   static int staticI=1; //staticVariable
   static void staticM(){} //staticMethod
  
   //Inner class
   class InnerClass {
         public void method() {
                 System.out.println("In InnerClass's method");
                
                 i=1; //OuterClass instanceVariable
                 m(); //OuterClass instanceMethod
                
                 staticI=1; //OuterClass staticVariable
                 staticM(); //OuterClass staticMethod
                
                 System.out.println("OuterClass reference="+OuterClass.this);
                 System.out.println("InnerClass reference="+this);
                
            OuterClass.this.i=2;//Accessing OuterClass instanceVariable using OuerClass reference
            OuterClass.this.m();//Accessing OuterClass instanceMethod using OuterClass reference
                
         }
   } //End InnerClass
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class InnerClassTest {
   public static void main(String[] args) {
     
      //Creating instance of InnerClass
      new OuterClass().new InnerClass().method();
     
   }
     
}
/*OUTPUT
In InnerClass's method
OuterClass reference=com.ankit.OuterClass@1a4eb98b
InnerClass reference=com.ankit.OuterClass$InnerClass@2677622b
*/

To create instance of  the InnerClass we must create instance of OuterClass first.

When above program is compiled following .class files are formed >  
OuterClass.class > OuterClass
OuterClass$InnerClass.class  >InnerClass
InnerClassTest.class  >InnerClassTest (Main class)



2) Static nested class

  • 2.1) Method of nested class can only be static if nested class is a static nested class.
  • 2.2) Static nested class is considered as static member variable of outer class.
  • 2.3) StaticNestedClass has access to all static member variables and static methods of OuterClass.
  • 2.4) StaticNestedClass can be abstract or final.
  • 2.5) StaticNestedClass can be private, protected, public.
  • 2.6) strictfp modifier can also be used with StaticNestedClass.

  • 2.7) Static nested classes can declare static initialization blocks
  • 2.8) Static nested classes can declare member interfaces.
  • 2.9) Static nested classes can declare static members
  • 2.10) Static nested classes can declare constant variables
  • 2.11) Static nested classes can inherit static members that are not constant variables.
  • 2.12) Static nested classes can declare instance initialization blocks
class OuterClass {
   // StaticNestedClass
   static class StaticNestedClass {
          // StaticNestedClass can declare static initialization blocks
          static {
          }
          // StaticNestedClass can declare member interfaces.
          interface I {
          }
          // StaticNestedClass can declare static members
          static int i = 2;
          // StaticNestedClass can declare constant variables
          static final int j = 3;
 
          //StaticNestedClass classes can declare instance initialization blocks
          {}
         
          //StaticNestedClass constructor
          StaticNestedClass() {}

     }
}

  • 2.13) Static nested classes cannot be declared in abstract class.
  • 2.14) Static nested classes cannot be declared in interface.


Program for accessing static nested class>
package com.ankit;
class OuterClass{
   static int staticI=1; //staticVariable
   static void staticM(){} //staticMethod
  
   //static Nested class
   static class StaticNestedClass {
          public void method() {
                 System.out.println("In StaticNestedClass's method");
                
                 staticI=1; //OuterClass staticVariable
                 staticM(); //OuterClass staticMethod
                
                 //System.out.println("StaticNestedClass reference="+this); //allowed
                
                
          }

   }//End StaticNestedClass
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class NestedClassTest {
   public static void main(String[] args) {
     
      //Accessing method of StaticNestedClass
      new OuterClass  .    StaticNestedClass().method();
     
   }
     
}
/*OUTPUT
In StaticNestedClass's method
*/


  • To access method of  the StaticNestedClass we need not to create instance of OuterClass.



Difference between static and non-static class>
Static class
class (Non-static class)
Top level class can never be static in java.
Top level class is always non static in java.
static class are also known as static nested classes.
Top level class is just called as class .
But,
nested class is known as >
  • inner class or
  • member inner class.
Only Static member variables of outer class can be accessed inside methods of static nested class.
Static and non-static member variables of outer class can be accessed inside methods of non-static class
Accessing method of static nested class

new OuterClass .    StaticNestedClass().method();

-Instance of top level class is not needed, we need to have instance of static nested class only
Accessing method of inner class

new OuterClass().new InnerClass().method();

Instance of top level class and InnerClass is needed.
         



When above program is compiled following .class files are formed >  
OuterClass.class > OuterClass
OuterClass$StaticNestedClass.class >StaticNestedClass
InnerClassTest.class  >InnerClassTest (Main class)

Note : Static nested class is not a inner class, its just a nested class.

3) Local inner class
  • 3.1) LocalInnerClass can be accessed inside method in which it has been created.
  • 3.2) LocalInnerClass has access to all other member variables of OuterClass like InnerClass.
  • 3.3) LocalInnerClass can be abstract or final.
  • 3.4) LocalInnerClass can’t be static.
  • 3.5) LocalInnerClass can’t be private, protected, public.
  • 3.6) LocalInnerClass can be declared in Expressions, Statements, and Blocks.
class OuterClass{
   //LocalInnerClass inside instance block
   {
          class A{}
   }
  
   //LocalInnerClass inside static block
   static{
          class A{}
   }
  
   void myMethod(){
          //LocalInnerClass inside if statement
          if(true){
                 class A{}
          }
                
          //LocalInnerClass inside for loop statement
          for(int i=0;i<1;i++){
                 class A{}
          }
   }
  
}



Program for accessing local inner class>
package com.ankit;
class OuterClass{
   int i=1; //instanceVariable
   static int staticI=1; //staticVariable
  
  
   //Inside this method we'll declare local class.
   void myMethod(){
          //Local Inner class
          class LocalInnerClass {
                 public void method() {
                       System.out.println("In LocalInnerClass's method");
                      
                       i=1; //OuterClass instanceVariable
                       staticI=1; //OuterClass staticVariable
                      
                       System.out.println("OuterClass reference="+OuterClass.this);
                       System.out.println("InnerClass reference="+this);
                      
                 }
          } //End LocalInnerClass
         
          //Creating instance of LocalInnerClass
          new LocalInnerClass().method();
  
   }
  
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class InnerClassTest {
   public static void main(String[] args) {
     
      //Creating instance of OuterClass
      new OuterClass().myMethod();
     
   }
     
}
/*OUTPUT
In LocalInnerClass's method
OuterClass reference=com.ankit.OuterClass@2677622b
InnerClass reference=com.ankit.OuterClass$1LocalInnerClass@67ce08c7
*/


When above program is compiled following .class files are formed >  
OuterClass.class > OuterClass
OuterClass$1LocalInnerClass.class >LocalInnerClass
InnerClassTest.class  >InnerClassTest (Main class)



4)  Anonymous Inner Class

Meaning of Anonymous in english dictionary is unknown name.
In java, AnonymousInnerClass means class with no name.

Program 1 for creating and using AnonymousInnerClass - And understanding how AnonymousInnerClass extend class>

class OuterClass{
   void m(){
          System.out.println("m()");
   }
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class InnerClassTest {
   public static void main(String[] args) {
         
          //Anonymous inner class
          OuterClass obj=new OuterClass(){
                
                 //Override m() method of OuterClass
                 void m(){
                       System.out.println("overridden m()");
                 }
          };
         
          obj.m(); //calls overridden m()
   }
     
}
/*OUTPUT
overridden m()
*/

What happened in above program was >
AnonymousInnerClass was created which extends OuterClass, m() method of OuterClass was overridden in AnonymousInnerClass.
Note :  AnonymousInnerClass extends OuterClass, without explicit use of extends keyword.


When above program is compiled following .class files are formed >  
OuterClass.class > OuterClass
InnerClassTest$1.class >AnonymousInnerClass
InnerClassTest.class  >InnerClassTest (Main class)


Program 2 for understanding more about AnonymousInnerClass >
class OuterClass{
   void m(){
          System.out.println("m()");
   }
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class InnerClassTest {
   public static void main(String[] args) {

          //Anonymous inner class
          new OuterClass(){
                
          }.m();      
   }
     
}
/*OUTPUT
m()
*/

What happened in above program was >
AnonymousInnerClass was created which extends OuterClass, m() method of OuterClass was inherited in AnonymousInnerClass.
Note :  AnonymousInnerClass extends OuterClass, without explicit use of extends keyword.




Program 3 to understand how AnonymousInnerClass implement interface>
AnonymousInnerClass cannot implement more than one interface. Let’s create a program >
interface MyInterface{
   void m();
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class InnerClassTest {
   public static void main(String[] args) {
         
          //Anonymous inner class
          new MyInterface(){ //implementing interface
                 public void m(){ //Provide implementation of MyInterface's m() method
                       System.out.println("implementation of MyInterface's m() method");
                 }
          }.m();      
   }
     
}
/*OUTPUT
implementation of MyInterface's m() method
*/

Note :  AnonymousInnerClass implements MyInterface, without explicit use of implements keyword.




Program 4 to understand how AnonymousInnerClass can implement more than 2 interfaces >
Though, AnonymousInnerClass can implement more than one interface in following way >
Let’s create MyInterface which will extend Runnable interface. Now, AnonymousInnerClass will implement 2 interfaces.
interface MyInterface extends Runnable{
   void m();
}
/**
*  Copyright (c), AnkitMittal JavaMadeSoEasy.com
*  Main class
*/
public class InnerClassTest {
   public static void main(String[] args) {
         
          //Anonymous inner class
          new MyInterface(){ //implementing interface
                 @Override //Provide implementation of MyInterface's m() method
                 public void m(){
                       System.out.println("implementation of MyInterface's m() method");
                 }
                 @Override //Provide implementation of Runnable's run() method
                 public void run() {
                 }
          }.m();      
   }
     
}
/*OUTPUT
implementation of MyInterface's m() method
*/




RELATED LINKS>


Static keyword in java - variable, method, class, block - 24 salient features


Difference between String, StringBuffer and StringBuilder in java - In depth coverage


eEdit
Must read for you :