Learnitweb

Inner class in Java

An Inner class is one class defined in another class. So inner class is a member of another class just like member variables and methods.

1.1 Types of inner class

There are four types of inner classes depending on where you define the inner class:

  1. Inner classes (a non-static class defined as member of another class)
  2. Method-local inner classes
  3. Anonymous inner classes
  4. Static nested classes

1.2 Use case and example of inner class

A class contains member variables and methods. Member variables define what kind of data a class holds. For example, a class ‘Car’ can look like this:

Car {
	String brand;
	String model;
	String color;
}

As mentioned earlier, an inner class is defined as a member of another class just like a member variable and method. We define an inner class when a class is a part of another class and there is not much significance of that class if defined outside that class. An inner class is tightly coupled with the outer class and has special relationship with the outer class.

Let us understand this with an example. In our ‘Car’ class, we can define a member ‘Engine’ as an inner class.

Car {
	String brand;
	String model;
	String color;
	
	// car methods
	
	//Engine as inner class
	Engine {
		int rpms;
		String brand;
		
		//engine methods
	}
} 

Here, Engine class is tightly coupled with Car and Engine is a component of Car. An engine has not much significance outside a car. So Engine is a very good candidate of being an inner class.

Another example, a body organ, like heart, kidney etc. can be created as an inner class of Body class. This is because an organ is a component of a body and has no significance outside a body.

However, there is always a discussion that we can create a separate class and then create a reference variable instead of creating an inner class.

1.3 Benefits of inner class

  • If a class has significance to only one class and is more meaningful to be an integral part of another class, we can define it as inner class. This becomes packaging of code easy.
  • Inner classes implement encapsulation.
  • Inner classes help writing more readable and maintainable code. For example, anonymous inner class helps in creating on the fly object and closer to where it is required as in case of event listeners. This code is more meaningful and easier to read.
  • Inner class concept logically group classes at one place and closer to one another.

2. Regular Inner Class

Now, we’ll discuss a regular inner class i.e., an inner class which is not static, method-local and anonymous.

class Outer {
	class Inner { }
}

When you compile this class, two .class files are generated, one for Outer and another for Inner.

> javac Outer.java

The generated class files are:

  • Outer.class
  • Outer$Inner.class

However, you can not run the inner class the same way as any other class. So the following is not going to work:

> java Outer$Inner

2.2 Modifiers which can be applied to inner class

An inner class is a class defined inside another class. A regular inner class is just like another member of outer class like member variables and methods. Following modifiers can be applied to an inner class:

  1. abstract
  2. public
  3. private
  4. protected
  5. final
  6. strictfp
  7. static (static modifier when applied to inner class changes it to static nested class)

2.3 Instantiating an Inner Class

Instance of inner class can not be created without the outer class. An inner class instance always needs an outer class instance.

We’ll see two ways to create instance of inner class – creating inner class instance from within outer class and creating an inner class instance outside the outer class instance.

2.3.1 Creating an instance of inner class within the outer class

You can create an instance of inner class inside the outer class. The instance of inner class can be created just like any other class using new.

public class Outer {
	public void createInner() {
		Inner inner = new Inner();
	}
	
	class Inner {
		public void sayHello() {
			System.out.println("hello world");
		}
	}
} 

As you can see in the above example, Outer is able to create instance on Inner using new just like any other class.

2.3.2 Creating an instance of inner class outside the outer class

As we have already mentioned, instance of inner class can not stand alone and needs outer class instance. To create an instance from outside the non-static outer class code, we first need the outer class instance and then you can use the following syntax to create inner class instance:

Outer.Inner inner = outer.new Inner();  //outer is Outer class' instance
package com.learnitweb;

class Outer {
	class Inner {
		public void sayHello() {
			System.out.println("hello world");
		}
	}
}

public class Test {
	public static void main(String args[]) {
		Outer outer = new Outer();  //create Outer instance
		Outer.Inner inner = outer.new Inner(); // create Inner instance
		inner.sayHello();
	}
}

Output

hello world

2.4 Reference Inner or Outer Instance from within Inner class

  1. To refer the inner class instance from within the inner class, use this.
  2. To refer the outer class instance from within the inner class, use Outer.this. Here, Outer is the name of the outer class.

Let us see this with the help of an example.

class Outer {
	private int x = 5;
	class Inner {
		int y = 7;
		public void testRef() {
			System.out.println("referencing y of inner " + this.y);
			System.out.println("referencing outer " + Outer.this);
			System.out.println("referencing x of outer " + Outer.this.x);
		}
	}
}

public class Test {
	public static void main(String args[]) {
		Outer outer = new Outer();
		Outer.Inner inner = outer.new Inner();
		inner.testRef();
	}
}

Output

referencing y of inner 7
referencing outer com.learnitweb.Outer@15db9742
referencing x of outer 5

Note: Inner class can access private members of outer class. Inner class is a member of outer class and has no problem in accessing any other member of outer class.