Learnitweb

Local class in Java

A local class is a class defined in a block. A block is a group of zero or more statements enclosed between braces.

Note: A local class can be defined inside any block, like a for loop, or if clause. A very common place of defining a local class is within a method.

1.1. Local class within a method

A method local inner class is an inner class defined within a method.

public class Outer {
	void print() {
		class MethodLocalInner {
			//code of method local inner class
		}
	}
}

In this code, MethodLocalInner class is defined in print() method of Outer class. But defining a method local inner class does not mean you can use it. To use a method local inner class, you have to first instantiate it.

1.2 Local class within a for loop

A class can also be defined within a for loop.

public class Outer {
	void print() {
		for(int i=0; i<5; i++) {
			class Inner {
				// code of inner class
			}
		}
	}
}

1.3 Local class within a if clause

A class also be defined within a if clause

public class Outer {
	void print() {
		if(1 == 1) {
			class Inner {
				//code of inner class
			}
		}
	}
}

Note: Since the method local inner classes are commonly used, we’ll discuss local classes with respect to defined within the method.

2. Creating an instance of a method local inner class

You can instantiate a method local inner class inside the method but outside and below the inner class. Following are the rules to instantiate a method local inner class:

  • Instance should be created inside the method.
  • Instance should be created outside the inner class.
  • Instance should be created below the definition of inner class. You can not instantiate the method local inner class inside the method but above the inner class definition, i.e. before defining the inner class.
public class Outer {

	//method inside outer class
	void print() {
		
		//inner class inside method
		class MethodLocalInner {
		
		}
		
		//instance of method local inner class inside method
		MethodLocalInner obj = new MethodLocalInner();
	}
}

2.1 Files generated after compilation

When a program containing method local inner class is compiled, two files are generated:

  1. class file for outer class
  2. class file for inner class having reference to the outer class.

When we compile the above code, following files will be generated:

  1. Outer.class
  2. Outer$1MethodLocalInner.class

3. Important points about method local inner class

  1. The scope of local inner class is restricted to the block they are defined in.
  2. A method local inner class can only be instantiated within the method where it is defined.
  3. A method local inner class can not be instantiated inside any other(other than the method where method local inner class is defined) method of outer class or anywhere else within the outer class.
  4. A method local inner class can access the private members of the outer class.
  5. A method local inner class can not be marked as public, private, protected and static. This rule is same as rule applicable for modifiers which can be used within a method.
  6. You can apply abstract and final modifiers to a method local inner class. But both can not be applied at the same time.
  7. A local inner class defined inside a static method can only access static members of the outer class. It can not access the instance variables as there is no associated instance of the outer class.
  8. Till JDK 7, local inner class can access only final local variables of the enclosing block. However from Java 8, it is possible to access the non-final local variables of enclosing block in local inner class.

4. Example of local class and its usage

In this program, we have defined a method local inner class Inner. We have also created an instance of Inner class which is named as inner.

In this program, we have also demonstrated that Inner class can access the local final member variable and private member variable of outer class.

public class Outer {
	private int a = 10;
	
	void print() {
		final int x= 7;
		
		class Inner {
			private void printInner() {
				//trying to access local variable x gives error
				System.out.println("local variable x inside local class : " + x);
				
				//trying to access private variable of outer class
				System.out.println("instance variable a inside local class : " + a);
			}
		}
		
		Inner inner = new Inner();
		inner.printInner();
	}
	
	public static void main(String args[]) {
		Outer outer = new Outer();
		outer.print();
	}
}

Output

local variable x inside local class : 7
instance variable a inside local class : 10

5. Why the inner class object cannot use the local variables (unless declared final) of the method the inner class is defined in

The reason is, local variable are created in stack. The local variables live till the execution of the method. When the method execution is over, the stack is destroyed and the memory is released. Whereas, the class’ object is created in heap.

So it is possible that the class object might be still alive even after the execution of the method. This is possible when the reference to the inner class is passed to some other code which saves this reference. This will create problem. We can say that it is possible that inner class object may outlive the instance variable. So inner class object can not use the local variables unless declared final.

package com.learnitweb;

public class Outer {
	void print() {
		int x= 7;
		
		class Inner {
			private void printInner() {
				//trying to access local variable x gives error
				System.out.println("x: " + x);
				
				//trying to access private variable of outer class
				
			}
		}
		
		//create instance of local class
		Inner inner = new Inner();
		inner.printInner();
	}
	
	public static void main(String args[]) {
		Outer outer = new Outer();
		outer.print();
	}
}

The above code will not compile with Java 7 and will give compilation error: Cannot refer to the non-final local variable x.

To fix this error declare x as final in above code.

final int x = 7;