Java Nested Class

While we define a class within another class then it is called nested class. Nested class are divided into two parts.

  1. Static
  2. Non Static(Inner Class)

Non Static or Inner class further divided into three parts.

  1. Inner Class
  2. Method Local Inner Class
  3. Anonymous Inner Class

Nested Class Advantages

  • It is used to logically group classes that are only used in one place.
  • It increases encapsulation as nested class will not be available to outside.
  • It can lead to more readable and maintainable code.

Static Nested Class

A static nested class is associated with its outer class. A static nested class cannot refer directly to instance variables or methods defined in outter class.

Syntax to define to static nested class

 class OutterClassName{
   static class NestedClassName{

   }
 }

Features of Static Nested Class

  • It can be instantiated independently, i.e. an object of outer class is not required for the instantiation of this class.
  • It can refer all static data members of its outer class irrespective of their scope.

Syntax to create object of Static Nested Class

 outerClassName.InnerClassName refObj = new outerClassName.InnerClassName();

Example of Static Nested Class

package com.startwithjava.oops;

public class TestOutter {
  static int num=10;  
  public static class Inner{
	 public void display() {
		 System.out.println("Test");
	 }
  }
  public static void main(String args[]) {
	  TestOuter.Inner obj=new TestOuter.Inner();  
	  obj.display();  
  }
}

After compilation contents of inner class are contained in a separate class file which is named according to the following convention.

OutterClassName$InnerClassName

For above example complier will create a class named TestOutter$Inner.

Non-static Inner Class

A class that is defined within the scope of another class and is not qualified by static keyword is called non-static inner class.

Syntax to define to non-static inner class

 class OutterClassName{
    class NestedClassName{

   }
 }

Features of Non-static Nested Class

  • It cannot be instantiated independently, i.e. an object of outer class is required to create object of this class.
  • It can access static as well as non-static data members of its outer class irrespective of their scope.
  • You cannot access outter class data members in contructors of inner class.

Example of Inner Class

package com.startwithjava.oops;
class TestOutter{
	public int a;
	private static int x = 10;
	
	public TestOutter(){
		a = 0;
	}
	public TestOutter(int a){
		this.a = a;
	}
	
	public class Inner{
		private int b;
		public Inner() {
			b=0;
		}
		public Inner(int b) {
			this.b = b;
		}
		public void display() {
			System.out.println("X="+x);
			System.out.println("A="+a);
			System.out.println("B="+b);
		}
	}
}
public class TestInnerClass {

	public static void main(String[] args) {
		TestOutter tobj = new TestOutter(25);
		TestOutter.Inner inObj = tobj.new Inner(50);
		inObj.display();
	}

}

Output


X=10
A=25
B=50

Method Local Inner Class

In Java, we can define a class within a method and the scope of the local inner class is restricted within the method. We can create objects within the method only.

Points to remember for Method Local Inner Class

  1. Method local inner class cannot access non-final local data members till JDK 1.7. From JDK 1.8, it is possible to access the non-final local data members in method local inner class.
  2. A Local Method Inner class cannot be accessed outside the method.

When to use Method Local Inner Class

A method-local class can increase the readability of your code by keeping related parts in one place. Suppose you have a method that needs to create a thread to do something in the background. Two ways to do this.

  • Either by creating a separate class which extends Thread class. This class would not used anywhere except that method then it is not recommended to create a separate class for it.
  • Second way which recommended, by creating method local innner class which extends Thread class or implements Runnable interface.
class MethodLocalInnerTest {
    void method1() {
       
        class Inner extends Thread{
           public void run(){
             //write code here to perform background operations
             dosomethinghere();
          }
        }
        new Inner().start();
    }
}

Anonymous class

Anonymous classes enable you to declare and instantiate a class at the same time. They are same as method local inner classes except that they do not have a name. We can use it if you need to use a local class only once.

Points to remember for Method Anonymous Class

  • An anonymous class has access to the members of its enclosing class.
  • Before Java 8, it was not possible to access local variables in its enclosing scope that are not declared as final but from Java 8 it is allowed.
  • You cannot declare static initializers or member interfaces in an anonymous class.
  • An anonymous class can have static members provided that they are constant variables.
  • You can define extra method in Anonymous class and can also declared data members.
  • You can define instance initializers.

Example 1


package com.startwithjava.oops;
public class AnonymousClassExample2 {
 public static void main(String[] args) { 
Runnable r = new Runnable() { 
public void run() { 
 for(int i=0;i<10;i++) {
  try { Thread.sleep(2000); }
  catch (InterruptedException e) {
   e.printStackTrace(); 
  } 
 System.out.println(" Invoked I="+i); 
 }
 } 
}; 
Thread th = new Thread(r); 
th.start();
 }
}

Example 2

 


package com.startwithjava.oops;
public abstract class Animal { 
protected String name; 
protected String food; 
Animal(){ super(); } 
Animal(String name,String food){
this.name = name; this.food = food;
} 
public abstract void action();
}
package com.startwithjava.oops;
public class AnonymousClassExample {
 public static void main(String[] args) { 
   Animal dog = new Animal("Dog","Meat") { 
   { 
    System.out.println("Instance Block 1"); 
   } 
   public void action() { 
    System.out.println(this.name+" Barks");
    System.out.println("Dog loves to eat "+this.food); 
   } 
   };
  Animal lion = new Animal("Lion","Fresh Meat") {
  { 
   System.out.println("Instance Block 2"); 
  }
  public void action() {
   System.out.println(this.name+" roars");
   System.out.println("Dog loves to eat "+this.food);
  }
 };
 dog.action();
 lion.action();
 }
}

Leave a Reply