Java Nested/Inner Classes

Similar to variable and methods, java allows us to create a class within another class. Classes defined inside another classes are known as nested classes. This tutorial explains different details of nested classes like types of nested classes, program of nested classes, why we use nested classes, when we use nested classes etc. The basic syntax of a nested class is :

 class OuterClassName {
    ...
    class NestedClassName {
       ...
    }
 }   

Types of Nested classes in Java

Nested classes are divided into two categories: static and non-static. Nested classes that are declared using static keyword are called static nested classes. Non-static nested classes are called inner classes. Nested classes can be divided as below :

  • Non-static nested class (inner class)
    • Member inner class
    • Local inner class
    • Anonymous inner class
  • Static nested class

Does java creates different .class files for nested or inner classes ?

Yes, Java compiler creates different .class file for outer and inner class of a program after compilation. Generally the inner class .class file name is made with combination of outer and inner class name with $ sign in between like OuterClassName$InnerClassName.class

Member Inner class

A class defined inside another class but outside any method or block is known as member inner class. These classes act as a member of outer class similar as member variables and methods. The basic syntax of declaring a member inner class is :

 class OuterClassName {
    ...
    access_modifier class MemberInnerClassName {
       ...
    }
 } 
 
 Example :
 
 class OuterClass {
    ...
    public class InnerClass {
       ...
    }
 }   

Some of the key points about the member inner classes are :

  • It can have all type of access modifiers(public, private, protected or default) in it's declaration. Remember, the outer most class can have only public and default(no modifier) modifier in it's declaration.
  • These classes can also be declared as abstract or final.
  • It can access any member of the outer class, no matter whether they are static, private or anything else.
  • These classes can only define non-static members inside it.
  • Like instance variables and methods, inner classes are also associated with an instance of the outer class.

Remember a class can not be declared as abstract and final together, no matter whether it's an inner or outer class. We will discuss about abstract and final classes in later tutorials.

How to create object of member inner class ?

Since these classes belongs to an object, you should create the object of its outer class first then create the object of inner class using the outer class object like below :

 OuterClassName outer = new OuterClassName();
 OuterClassName.InnerClassName inner = outer.new InnerClassName();

Here OuterClassName and InnerClassName is the name of outer and inner class respectively while outer and inner is the name of outer and inner class object respectively.

As you can access member variables of a class directly inside a non-static method, similarly you can directly create the object of member inner class inside a non-static method of outer class, as given in below program inside the run method. Remember outside the outer class, you must need the reference of outer class to create the object of member inner class.

Member inner class program in Java

 class OuterClass {
    int outerVar = 100;
 
    class MemberInnerClass {
        int innerVar = 50;
         
        int getSum(int param) {
            return innerVar +  outerVar + param;
        }       
    }
     
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        OuterClass.MemberInnerClass inner = outer.new MemberInnerClass(); 
        System.out.println(inner.getSum(10));
        outer.run();
     }     
    void run() {
        MemberInnerClass memberInner = new MemberInnerClass();// Creating object directly
        System.out.println(memberInner.getSum(20));
    }
 }

Save above program as OuterClass.java, compile as javac OuterClass.java. Java compiler will create two .class file, OuterClass.class and OuterClass$MemberInnerClass.class for above program.
Run as java OuterClass

Output:

160
170

Local or method local Inner class

Local inner class is a class which is defined inside a method or block of outer class, like local variables. It can be defined inside static or non-static method. These classes are accessible within the method only, similar as local variables. The key points about the local inner classes are :

  • They cannot have access modifiers(public, private, protected) in their declaration.
  • The only modifiers that you can use with local inner class declaration are abstract and final.
  • They can access any member of outer class, no matter whether they are static, private or anything else.
  • These classes can only define non-static members inside them.
  • They can access only final variables of it's enclosing method. Accessing non-final variables of it's enclosing methods will result in compilation error.

How to create object of local inner class ?

Creation of local inner class object is similar as creation of normal objects like below. You don't need the reference of outer class object, as local inner class belongs to method only.

 LocalInnerClassName objName = new LocalInnerClassName();

Here LocalInnerClassName is the name of local inner class while objName is the name of local inner class object.

Java program of local inner class

 class OuterClass {
    int outerVariable = 100;
    static int staticOuterVariable = 200;
     
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        int sum =  outer.run();
        System.out.println("Total sum = "+ sum);
      }     
    public int run() {
        int localVar = 50;
        final int finalLocalVariable = 60;         
         // Creating local inner class
        class LocalInnerClass {
            int innerVariable = 20;
             
            int getSum(int parameter) {
                // Cannot access localVar here as it's not declared as final
                return outerVariable + staticOuterVariable + finalLocalVariable +
                   innerVariable + parameter;
              }       
           }
        LocalInnerClass local = new LocalInnerClass();
        return local.getSum(10);
     }
  }

Save above program as OuterClass.java, compile as javac OuterClass.java and run as java OuterClass

Output:

Total sum = 390

Anonymous Inner Class

An anonymous inner class is a class that has no name. These classes are usually declared inside a method or block, but it can be defined outside a method or block as well. They are generally used to define an implementation of interface or abstract class. It can be a re-implementation of a normal or super class as well. The key points about anonymous inner classes are :

  • They cannot have access modifiers(public, private, protected) in their declaration.
  • These classes ends with a semicolon(;) after curly braces }.
  • They can access any member of outer class, no matter whether they are static, private or anything else.
  • These classes can only define non-static members inside it, not static members.
  • This is the only type of inner class that cannot define constructors since it doesn't have a name.
  • These classes can be defined as a parameter inside a method as well.

How to create anonymous inner class ?

The creation of anonymous inner class is little different than normal class creation. It starts with new keyword followed by the name of class/interface that need to be implemented. It's similar as constructor creation except that it has a body. These classes are declared and used to create one object in a single statement. The creation of anonymous class looks like below :

 // As implementation of a class
 new ClassName() {
  // class body
 }; 
 // Here parameters will be passed to constructor of defined ClassName.
 new ClassName(parameters) {
  // class body
 };
 // As implementation of interface
 new InterfaceName() {
  // class body
 };
 // Or It can be defined like below as well
 ClassOrInterfaceName objName = new ClassOrInterfaceName() {
  // class body
 };
 

Here ClassName/InterfaceName/ClassOrInterfaceName is not the name of anonymous class, it's already defined an abstract class, superclass, normal class or interface name.

Anonymous inner class program in Java

The program below defines a simple abstract class first. The anonymous class implements this abstract class.

 abstract class MyAbstractClass {
    abstract void run();
 }

 class OuterClass {
   public static void main(String args[]) { 
     
        MyAbstractClass obj = new MyAbstractClass() { // Start of anonymous class body
           int innerVariable = 100;  
              
           public void run() {
              System.out.println("innerVar = "+ innerVariable);
              System.out.println("Inside anonymous inner class method");
            }
         }; // End of anonymous class
      obj.run();
    }
 }

Save above program as OuterClass.java, compile as javac OuterClass.java and run as java OuterClass

Output:

innerVar = 100
Inside anonymous inner class method

Static Nested class

Classes that are defined inside the class but outside any method or block using static keyword are called static nested classes. These classes act as static member of outer class which means these classes belongs to outer class, not the object of outer class. The key points about static nested classes are :

  • It can have all type of access modifiers(public, private, protected or default) in it's declaration.
  • These classes can also be declared as abstract or final.
  • It can not access non-static members of outer class directly but using outer class object it can access them.
  • It can define both static and non-static members inside it's body.
  • You can access these classes directly inside the containing/outer class. To access from a class outside the containing class, use the syntax OuterClassName.StaticClassName.

How to create object of static nested class ?

Inside the outer(enclosing) class, you can directly create the object of static nested class, but outside that, you need the outer class name to create the object of static nested class.

 // Inside outer/enclosing class
 StaticClassName objName = new StaticClassName();
 // Outside the outer class
 OuterClassName.StaticClassName objName = new OuterClassName.StaticClassName();

Here OuterClassName and StaticClassName is the name of outer class and static nested class respectively while objName is the name of static nested class object.

Can I create object of static nested class using outer class object ?

No you can not, since these classes belongs to class(outer class) and not to an instance of the outer class, doing so will result in compilation error.

Static nested class program in Java

 class OuterClass {
    int outerVariable = 50;
    static int staticOuterVariable = 100;
 
    static class StaticNestedClass {
        int innerVariable = 10;
         
        int getSum(int parameter) {
            // Cannot access outerVariable here directly as it's not static
            return innerVariable + staticOuterVariable + parameter;
        }       
    }
     
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        StaticNestedClass inner = new StaticNestedClass(); 
        System.out.println("Sum = "+ inner.getSum(20));
        outer.run();
      }     
    void run() {
        StaticNestedClass inner = new StaticNestedClass();
        System.out.println("Inside run method, Sum = "+ inner.getSum(40));
    }
 }

Save above program as OuterClass.java, compile as javac OuterClass.java and run as java OuterClass

Output:

Sum = 130
Inside run method, Sum = 150

Why we use nested class in Java

There are couple of reasons for using nested classes which includes the following :

  • Nesting of classes is a way of logically grouping classes that are only used in one place. If your class is useful to only one other class, then it's logical to include it in that class and keep both classes together.
  • Nesting of classes helps to write more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used which makes easy for programmer to read and modify the code whenever required.
  • Nesting also increases encapsulation. Consider classes A and B, where B needs access to members of A which needs to be declared as private. By hiding class B within class A, A's members can be declared private and B can access them. Furthermore, B itself will be hidden from the outside world.

When to use nested classes in Java

When you know that your class is going to be used by one class only or your class will act as a helper class to it's outer class, you should make your class as inner class. Moreover if you know that the existence of your class is dependent on one other class only, declare your class as inner class inside that class. In java, HashMap class contains number of inner classes like KeySet, EntrySet, Node etc which acts as helper class to HashMap class.

★★★
  • A nested class can have another nested class inside it.
  • Nesting of classes can be done any number of time, however doing more than one level of nesting is not a good design as it increases complexity.
  • You can define different types of nested classes together inside a class.
  • Nested classes except anonymous class can extend/implement other classes or interfaces as well.
  • Anonymous class internally extends/implements implemented class/interface.
  • Using anonymous class object you can access variables and methods of implemented class/interface only. Any new variable or method defined inside anonymous class won't be accessible by it's object.
  • Members of all nested classes can have any access modifiers in their declaration.
  • You can also define nested class inside an interface.