Menu Close

Inner classes in Java

Inner class:

  • Define a class inside another class. It is also called nested class.
  • Inner classes clearly have two benefits one is ‘name control’ and second one is ‘access control’.
  • Defining more than one class with the same name and accessing them in the application is called “name control”. In Java, name control benefit is not as important because Java packages give the name control.
  • Access control refers ‘setting dependencies on objects’. Accessing object functionality with the permissions of another object.

The syntax for inner class is as follows:

[modifiers] class OuterClassName 
{
// code...
 [modifiers] class InnerClassName 
{
// code....
 }
}

Inner classes classified into:

  1. Static inner classes
  2. Non-static inner classes
  3. Local inner classes
  4. Anonymous inner classes

Class files generation for inner classes:

  • Compiler is intended for class files generation.
  • It has to generate class file for both Outer and Inner classes on compilation.
  • An inner class can be identified from its Outer class using a symbol ‘$’.

Following program explains clearly how compiler generates class files:

class Outer
{
	// ....code
	class Inner
	{
		// ....code
	}
}
class-files :	Outer.class 
		Outer$Inner.class

Accessing static members of static inner class:

  • Static members are called class level members in Java and we can access them using class Identity.
  • If the inner class is static along with its functionality, we can access the members as follows.
class Outer 
{
	static void m1()
	{
		System.out.println("Outer class static functionality...");
	}
	static class Inner
	{
		static void m2()
		{
			System.out.println("Inner class static functionality...");
		}
	}
}
class MainClass
{
	public static void main(String args[ ])
	{
		Outer.m1();
		// Outer.m2(); /* Error : */
		Outer.Inner.m2();
	}
}

Accessing non-static members of non-static inner class:

  • Generally non static members can be accessed using instance of class.
  • If inner class is non-static, we can instantiate by using Outer class Object.
  • Once instance is ready, we can access non static functionality of inner class.
class Outer 
{
	void m1()
	{
		System.out.println("Outer class non-static functionality...");
	}
	class Inner
	{
		void m2()
		{
			System.out.println("Inner class non-static functionality...");
		}
	}
}
class MainClass
{
	public static void main(String args[ ])
	{
		Outer outer = new Outer();
		outer.m1();
		// outer.m2(); /* Error : */

		Outer.Inner inner = outer.new Inner();
		inner.m2();
	}
}

Accessing Non-static members of Static inner class:

  • We can access non static members using object in java application.
  • We can instantiate inner class using outer class name if inner class is static.
class Outer 
{
	static class Inner
	{
		void m()
		{
			System.out.println("static Inner class non-static functionality...");
		}
	}
}
class MainClass
{
	public static void main(String args[ ])
	{
		Outer.Inner obj = new Outer.Inner();
		obj.m();
	}
}

Accessing static members of non-static inner class:

It is not allowed to define static members (free accessible) inside the non-static context (restricted access). Hence non-static inner class doesn’t have static declarations.

class Outer
{
	class Inner
	{
		static void fun() //Error :
		{
			System.out.println("Inner class static method");
		}
	}
}

private functionality of an object cannot be accessed by another object even in Parent-Child relation also:

class First
{
	private static int a=100;
}
class Second extends First
{
	public static void main(String[] args) 
	{
		System.out.println("a value : "+First.a);
	}
}

An Outer class can access even private members of inner class:

class Outer
{
	class Inner
	{
		private void method()
		{
			System.out.println("Inner class private method");
		}
	}
	public static void main(String args[ ])
	{
		Outer obj1 = new Outer();
		Outer.Inner obj2 = obj1.new Inner();
		obj2.method();
	}
}

We can simplify the above object construction process as follows:

class Outer
{
	class Inner
	{
		private void method()
		{
			System.out.println("Inner class private method");
		}
	}
	public static void main(String args[ ])
	{
		new Outer().new Inner().method();
	}
}

Static Members of Outer class are directly visible to inner class including private:

class Outer
{
	private static int x = 100 ;
	class Inner
	{
		private void method()
		{
			System.out.println("Outer's x val : "+Outer.x);
		}
	}
	public static void main(String args[ ])
	{
		new Outer().new Inner().method();
	}
}

Non-static members of outer class including private, can be accessed from the inner class as follows:

                <Outer_class_name>.this.<Outer_class_non-static-member>

class Outer
{
	private int x ;
	Outer(int x)
	{
		this.x = x ;
	}
	class Inner
	{
		int x ;
		Inner(int x)
		{
			this.x = x ;
		}
		private void method()
		{
			System.out.println("Outer's x val : "+Outer.this.x);
			System.out.println("Inner's x val : "+this.x);
		}
	}
	public static void main(String args[ ])
	{
		Outer obj1 = new Outer(100);
		Outer.Inner obj2 = obj1.new Inner(200);
		obj2.method();
	}
}