10.2 Types of inner class in Java: Normal inner class, Method local inner class, Anonymous inner class, and Static nested class.

By | March 17, 2022

1. Java Member Inner class

A non-static class that is created inside a class but outside a method is called member inner class. It is also known as a regular inner class. It can be declared with access modifiers like public, default, private, and protected.

Syntax:

class Outer{  
 //code  
 class Inner{  
  //code  
 }  
}  

Java Member Inner Class Example

In this example, we are creating a msg() method in the member inner class that is accessing the private data member of the outer class.

TestMemberOuter1.java

class TestMemberOuter1{  
 private int data=30;  
 class Inner{  
  void msg(){System.out.println(“data is “+data);}  
 }  
 public static void main(String args[]){  
  TestMemberOuter1 obj=new TestMemberOuter1();  
  TestMemberOuter1.Inner in=obj.new Inner();  
  in.msg();  
 }  
}  

Output:

data is 30

How to instantiate Member Inner class in Java?

An object or instance of a member’s 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:

Syntax:

OuterClassReference.new MemberInnerClassConstructor();  

Example:

obj.new Inner();  

Here, OuterClassReference is the reference of the outer class followed by a dot which is followed by the new operator.

Internal working of Java member inner class

The java compiler creates two class files in the case of the inner class. The class file name of the inner class is “Outer$Inner”. If you want to instantiate the inner class, you must have to create the instance of the outer class. In such a case, an instance of inner class is created inside the instance of the outer class.

Internal code generated by the compiler

The Java compiler creates a class file named Outer$Inner in this case. The Member inner class has the reference of Outer class that is why it can access all the data members of Outer class including private.

import java.io.PrintStream;  
class Outer$Inner  
{  
    final Outer this$0;  
    Outer$Inner()  
    {   super();  
        this$0 = Outer.this;  
    }  
    void msg()  
    {  
        System.out.println((new StringBuilder()).append(“data is “)  
       .append(Outer.access$000(Outer.this)).toString());  
   }  
}  

2. Java Anonymous inner class

Java anonymous inner class is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain “extras” such as overloading methods of a class or interface, without having to actually subclass a class.

In simple words, a class that has no name is known as an anonymous inner class in Java. It should be used if you have to override a method of class or interface. Java Anonymous inner class can be created in two ways:

  1. Class (may be abstract or concrete).
  2. Interface

Java anonymous inner class example using class

TestAnonymousInner.java

abstract class Person{  
  abstract void eat();  
}  
class TestAnonymousInner{  
 public static void main(String args[]){  
  Person p=new Person(){  
  void eat(){System.out.println(“nice fruits”);} 
};  
p.eat();  
 }  
}  

Output:

nice fruits

Internal working of given code

Person p=new Person(){  
void eat(){System.out.println(“nice fruits”);}  
};  

  1. A class is created, but its name is decided by the compiler, which extends the Person class and provides the implementation of the eat() method.
  2. An object of the Anonymous class is created that is referred to by ‘p,’ a reference variable of Person type.

Internal class generated by the compiler

import java.io.PrintStream;  
static class TestAnonymousInner$1 extends Person  
{  
   TestAnonymousInner$1(){}  
   void eat()  
    {  
        System.out.println(“nice fruits”);  
  }
}  

Java anonymous inner class example using interface

interface Eatable{  
 void eat();  
}  
class TestAnnonymousInner1{  
 public static void main(String args[]){  
 Eatable e=new Eatable(){  
  public void eat(){System.out.println(“nice fruits”);}  
 };  
 e.eat();  
 }  
}  

Output:

nice fruits

Internal working of given code

It performs two main tasks behind this code:

Eatable p=new Eatable(){  
void eat(){System.out.println(“nice fruits”);}  
};  

  1. A class is created, but its name is decided by the compiler, which implements the Eatable interface and provides the implementation of the eat() method.
  2. An object of the Anonymous class is created that is referred to by ‘p’, a reference variable of the Eatable type.

Internal class generated by the compiler

import java.io.PrintStream;  
static class TestAnonymousInner1$1 implements Eatable  
{  
TestAnonymousInner1$1(){}  
void eat(){System.out.println(“nice fruits”);}  
}  

3. Java Local inner class

A class i.e., created inside a method, is called local inner class in java. Local Inner Classes are the inner classes that are defined inside a block. Generally, this block is a method body. Sometimes this block can be a for loop, or an if clause. Local Inner classes are not a member of any enclosing classes. They belong to the block they are defined within, due to which local inner classes cannot have any access modifiers associated with them. However, they can be marked as final or abstract. These classes have access to the fields of the class enclosing it.

If you want to invoke the methods of the local inner class, you must instantiate this class inside the method.

Java local inner class example

LocalInner1.java

public class localInner1{  
private int data=30;//instance variable  
 void display(){  
  class Local{  
   void msg(){System.out.println(data);}  
  }  
  Local l=new Local();  
  l.msg();  
 }  
 public static void main(String args[]){  
  localInner1 obj=new localInner1();  
  obj.display();  
 }  
}  

Output:

30

Internal class generated by the compiler

In such a case, the compiler creates a class named Simple$1Local that has the reference of the outer class.

import java.io.PrintStream;  
class localInner1$Local  
{  
    final localInner1 this$0;  
    localInner1$Local()  
    {     
        super();  
        this$0 = Simple.this;  
    }  
    void msg()  
    {  
        System.out.println(localInner1.access$000(localInner1.this));  
    }  
}  

Rule: Local variables can’t be private, public, or protected.

Rules for Java Local Inner class

1) Local inner class cannot be invoked from outside the method.
2) Local inner class cannot access non-final local variable till JDK 1.7. Since JDK 1.8, it is possible to access the non-final local variable in the local inner class.

Example of local inner class with local variable

LocalInner2.java

class localInner2{  
 private int data=30;//instance variable  
 void display(){  
  int value=50;//local variable must be final till jdk 1.7 only  
  class Local{  
   void msg(){System.out.println(value);}  
  }  
  Local l=new Local();  
  l.msg();  
 }  
 public static void main(String args[]){  
  localInner2 obj=new localInner2();  
  obj.display();  
 }  
}  

Output:
50

4. Java static nested class

A static class is a class that is created inside a class, is called a static nested class in Java. It cannot access non-static data members and methods. It can be accessed by outer class name.

  • It can access static data members of the outer class, including private.
  • The static nested class cannot access non-static (instance) data members or

Java static nested class example with instance method

TestOuter1.java

class TestOuter1{  
  static int data=30;  
  static class Inner{  
   void msg(){System.out.println(“data is “+data);}  
  }  
  public static void main(String args[]){  
  TestOuter1.Inner obj=new TestOuter1.Inner();  
  obj.msg();  
  }  
}  

Output:

data is 30

In this example, you need to create the instance of static nested class because it has instance method msg(). But you don’t need to create the object of the Outer class because the nested class is static and static properties, methods, or classes can be accessed without an object.

Internal class generated by the compiler

import java.io.PrintStream;  
static class TestOuter1$Inner  
{  
TestOuter1$Inner(){}  
void msg(){  
System.out.println((new StringBuilder()).append(“data is “)  
.append(TestOuter1.data).toString());  
}    
}  

Java static nested class example with a static method

If you have the static member inside the static nested class, you don’t need to create an instance of the static nested class.

TestOuter2.java

public class TestOuter2{  
  static int data=30;  
  static class Inner{  
   static void msg(){System.out.println(“data is “+data);}  
  }  
  public static void main(String args[]){  
  TestOuter2.Inner.msg();//no need to create the instance of static nested class  
 }  
}  

Output:
data is 30

5. Java Nested Interface

An interface, i.e., declared within another interface or class, is known as a nested interface. The nested interfaces are used to group related interfaces so that they can be easy to maintain. The nested interface must be referred to by the outer interface or class. It can’t be accessed directly.

Points to remember for nested interfaces

There are given some points that should be remembered by the java programmer.

  • The nested interface must be public if it is declared inside the interface, but it can have any access modifier if declared within the class.
  • Nested interfaces are declared static

Syntax of nested interface which is declared within the interface

interface interface_name{  
 …  
 interface nested_interface_name{  
  …  
 }  
}   

Syntax of nested interface which is declared within the class

class class_name{  
 …  
 interface nested_interface_name{  
  …  
 }  
}   

Example of nested interface which is declared within the interface

In this example, we will learn how to declare the nested interface and how we can access it.

TestNestedInterface1.java

interface Showable{  
  void show();  
  interface Message{  
   void msg();  
  }  
}  
class TestNestedInterface1 implements Showable.Message{  
 public void msg(){System.out.println(“Hello nested interface”);}  
 public static void main(String args[]){  
  Showable.Message message=new TestNestedInterface1();//upcasting here  
  message.msg();  
 }  
}  

Output:

hello nested interface

As you can see in the above example, we are accessing the Message interface by its outer interface Showable because it cannot be accessed directly. It is just like the almirah inside the room; we cannot access the almirah directly because we must enter the room first. In the collection framework, the sun microsystem has provided a nested interface Entry. Entry is the subinterface of Map, i.e., accessed by Map.Entry.

Internal code generated by the java compiler for nested interface Message

The java compiler internally creates a public and static interface as displayed below:

public static interface Showable$Message  
{  
  public abstract void msg();  
}  

Example of nested interface which is declared within the class

Let’s see how we can define an interface inside the class and how we can access it.

TestNestedInterface2.java

class A{  
  interface Message{  
   void msg();  
  }  
}  
class TestNestedInterface2 implements A.Message{  
 public void msg(){System.out.println(“Hello nested interface”);}  
 public static void main(String args[]){  
  A.Message message=new TestNestedInterface2();//upcasting here  
  message.msg();  
 }  
}  

Output:

hello nested interface

Can we define a class inside the interface?

Yes, if we define a class inside the interface, the Java compiler creates a static nested class. Let’s see how can we define a class within the interface:

interface M{  
  class A{}  
}  

Leave a Reply

Your email address will not be published. Required fields are marked *