An Inner Class in Java is a class that is defined within another class. It is a member of the outer class and can access the members (fields and methods) of the outer class, including private members. Inner classes are used to logically group classes that are only used in one place or to increase the encapsulation of your code.
Java supports four types of inner classes
- Non-static Nested Class (Inner Class)
- Static Nested Class
- Local Class
- Anonymous Class
Non-static Inner Class
A non-static inner class is associated with an instance of the outer class and can access all the fields and methods of the outer class, including private ones.
Example:
//Main.java file
class OuterClass {
private String name = "John";
// Non-static inner class
class InnerClass {
void displayName() {
// Accessing outer class variable
System.out.println(name);
}
}
void createInnerInstance() {
InnerClass inner = new InnerClass(); // Creating an inner class object
inner.displayName(); // Calling method of inner class
}
}
public class Main {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.createInnerInstance();
}
}
Output:
Explanation:
- OuterClass has a private field name.
- The InnerClass is defined within OuterClass. It has access to the private field name from the outer class.
- You need an instance of the outer class to create an instance of the inner class, as inner classes are associated with outer class instances.
Static Nested Class
A static nested class is a nested class that is declared static. It can access only the static members of the outer class.
Example:
//Main.java file
class OuterClass {
private static String name = "John";
// Static nested class
static class StaticNestedClass {
void displayName() {
// Accessing static outer class member
System.out.println("My name is: "+name);
}
}
}
public class Main {
public static void main(String[] args) {
// You can directly create an instance of StaticNestedClass without an OuterClass instance
OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
nested.displayName();
}
}
Output:
Explanation:
- The StaticNestedClass can access only the static fields of the outer class, such as name.
- It does not require an instance of the outer class to be created.
Local Class
A local class is a class defined within a method, constructor, or block. It can access the local variables and parameters of the method (but only if they are final or effectively final).
Example:
//Main.java file
class OuterClass {
void outerMethod() {
final String localVariable = "I am a local variable";
// Local class inside the method
class LocalClass {
void display() {
System.out.println(localVariable);
}
}
// Create an instance of LocalClass and call its method
LocalClass local = new LocalClass();
local.display();
}
}
public class Main {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.outerMethod();
}
}
Output:
Explanation:
- LocalClass is defined inside the method outerMethod.
- It can access the local variables of outerMethod, but the variables must be final or effectively final to be accessed inside the local class.
Anonymous Class
An anonymous class is a class with no name and is used to instantiate objects of a class at the time of creation. It is often used when you want to implement an interface or extend a class without explicitly defining a new class.
Example:
//Main.java file
interface Animal {
void makeSound();
}
public class Main {
public static void main(String[] args) {
// Anonymous class implementing the Animal interface
Animal animal = new Animal() {
public void makeSound() {
System.out.println("Animal make sound.");
}
};
animal.makeSound();
}
}
Output:
Explanation:
- The anonymous class is created by instantiating the Animal interface and providing the implementation for the makeSound() method directly.
- There is no need to define a separate class with a name, which makes this approach compact and useful for short-term tasks.
Benefits of Using Inner Classes
- Encapsulation: Inner classes allow better encapsulation by keeping classes together that are logically related.
- Access to Outer Class Members: Inner classes can access all members (including private ones) of the outer class.
- Improved Code Organization: By grouping related classes together, inner classes help improve code organization, especially when an inner class is used only in one place.