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 of which local inner classes cannot have any access modifiers associated with them. However, they can be marked as final or abstract. These class have access to the fields of the class enclosing it. Local inner class must be instantiated in the block they are defined in.

A class i.e. created inside a method is called local inner class in java. If you want to invoke the methods of local inner class, you must instantiate this class inside the method.

Rules of Local Inner Class:
  1. He scope of local inner class is restricted to the block they are defined in.

  2. Local inner class cannot be instantiated from outside the block where it is created in.

  3. Till JDK 7,Local inner class can access only final local variable of the enclosing block. However From JDK 8, it is possible to access the non-final local variable of enclosing block in local inner class.

  4. A local class has access to the members of its enclosing class.

  5. Local inner classes can extend an abstract class or can also implement an interface.

inner class

Declaring a Local Inner class: A local inner class can be declared within a block. This block can be either a method body, initialization block, for loop or even an if statement.

Accessing Members: A local inner class has access to fields of the class enclosing it as well as the fields of the block that it is defined within. These classes, however, can access the variables or parameters of the block that encloses it only if they are declared as final or are effectively final. A variable whose value is not changed once initialized is called as effectively final variable. A local inner class defined inside a method body, have access to it’s parameters.

What happens at compile time?

When a program containing a local inner class is compiled, the compiler generate two .class files, one for the outer class and the other for the inner class that has the reference to the outer class. The two files are named by compiler as:

  1. Outer.class
  2. Outer$1Inner.class
Java local inner class example
public class Test { private int newdata=36;//instance variable void display(){ class Local{ void msg(){System.out.println(newdata);} } Local l=new Local(); l.msg(); } public static void main(String args[]){ Test obj=new Test(); obj.display(); } }

Internal class generated by the compiler

In such case, compiler creates a class named Simple$1Local that have 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)); } }

Note: Local variable can't be private, public or protected.

Example of local inner class with local variable
class Test { private int data=31;//instance variable void display(){ int value=36;//local variable must be final class Local{ void msg(){System.out.println(value);}//C.T.Error } Local l=new Local(); l.msg(); } public static void main(String args[]){ Test obj=new Test(); obj.display(); } }

Declaration within a method body
public class Outer { private void getValue() { int sum = 20; class Inner { public int divisor; public int remainder; public Inner() { divisor = 4; remainder = sum%divisor; } private int getDivisor() { return divisor; } private int getRemainder() { return sum%divisor; } private int getQuotient() { System.out.println("Inside inner class"); return sum / divisor; } } Inner inner = new Inner(); System.out.println("Divisor = "+ inner.getDivisor()); System.out.println("Remainder = " + inner.getRemainder()); System.out.println("Quotient = " + inner.getQuotient()); } public static void main(String[] args) { Outer outer = new Outer(); outer.getValue(); } }

Divisor = 5 Remainder = 0 Inside inner class Quotient = 6

Note :- A local class can access local variables and parameters of the enclosing block that are effectively final. For example, if you add the highlighted assignment statement in the Inner class constructor or in any method of Inner class in above example :

public Inner() { sum = 20; divisor = 4; remainder = sum%divisor; }

Because of this assignment statement, the variable sum is not effectively final anymore. As a result, the Java compiler generates an error message similar to “local variables referenced from an inner class must be final or effectively final”.

Declaration inside an if statement
public class Test { public int data = 50; public int getData() { return data; } public static void main(String[] args) { Test outer = new Test(); if(outer.getData() < 20) { // Local inner class inside if clause class Inner { public int getValue() { System.out.println("Inside Inner class"); return outer.data; } } Inner inner = new Inner(); System.out.println(inner.getValue()); } else { System.out.println("Inside Outer class"); } } }

Inside Outer class
Demonstrating Erroneous codes for Inner class
public class Test { private int getValue(int data) { static class Inner { private int getData() { System.out.println("Inside inner class"); if(data < 20) { return 5; } else { return 15; } } } Inner inner = new Inner(); return inner.getData(); } public static void main(String[] args) { Test outer = new Test(); System.out.println(outer.getValue(10)); } }

Compilation error

Explanation: The above program causes compilation error because the inner class cannot be declared

as static. Inner classes are associated with the block they are defined within and not with the external class(Outer in this case).

public class Test { private void myMethod() { class Inner { private void innerMethod() { System.out.println("Inside inner class"); } } } public static void main(String[] args) { Test outer = new Test(); Inner inner = new Inner(); System.out.println(inner.innerMethod()); } }

Compilation error