Java supports defining classes within other classes, known as inner classes. Inner classes are used to logically group classes that are only used in one place, increasing encapsulation and providing an easier way to handle complex functionality.
There are different types of inner classes in Java:
A member inner class is defined inside a class and is associated with an instance of the enclosing class. It can access the enclosing class’s members, including private members.
class OuterClass {
private int outerValue = 10;
// Member inner class
class InnerClass {
public void display() {
System.out.println("Outer value: " + outerValue);
}
}
public static void main(String[] args) {
// Creating an instance of the outer class
OuterClass outer = new OuterClass();
// Creating an instance of the inner class
OuterClass.InnerClass inner = outer.new InnerClass();
// Calling the method of the inner class
inner.display(); // Output: Outer value: 10
}
}
In this example:
InnerClass
is a member inner class inside the OuterClass
.outerValue
of the enclosing class.A static nested class is a nested class that is declared static. It does not have access to instance variables or methods of the outer class. It can, however, access static members of the outer class.
class OuterClass {
private static int staticValue = 20;
// Static nested class
static class StaticNestedClass {
public void display() {
System.out.println("Static value: " + staticValue);
}
}
public static void main(String[] args) {
// Creating an instance of the static nested class
OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
// Calling the method of the static nested class
nested.display(); // Output: Static value: 20
}
}
In this example:
StaticNestedClass
is a static nested class inside the OuterClass
.staticValue
of the outer class.A local inner class is defined within a method, constructor, or block. It is local to the scope where it is defined. Local inner classes can access the members of the enclosing class, including private members. However, they can only access local variables if they are declared final
or are effectively final (not modified after initialization).
class OuterClass {
public void outerMethod() {
int localVar = 30; // Effectively final variable
// Local inner class
class LocalInnerClass {
public void display() {
System.out.println("Local variable: " + localVar);
}
}
// Creating an instance of the local inner class
LocalInnerClass localInner = new LocalInnerClass();
localInner.display(); // Output: Local variable: 30
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.outerMethod();
}
}
In this example:
LocalInnerClass
is defined inside the method outerMethod()
.localVar
variable because it is effectively final.An anonymous inner class is an inner class that does not have a name. It is used to override methods or implement an interface. Anonymous inner classes are often used when you need to create a one-time-use class, such as for event handling or callback mechanisms.
interface Greeting {
void sayHello();
}
public class AnonymousClassDemo {
public static void main(String[] args) {
// Anonymous inner class implementing the Greeting interface
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello, world!");
}
};
greeting.sayHello(); // Output: Hello, world!
}
}
In this example:
Greeting
interface.new
keyword.class Animal {
public void makeSound() {
System.out.println("Some generic animal sound");
}
}
public class AnonymousClassDemo {
public static void main(String[] args) {
// Anonymous inner class extending the Animal class
Animal dog = new Animal() {
@Override
public void makeSound() {
System.out.println("Bark");
}
};
dog.makeSound(); // Output: Bark
}
}
In this example:
Animal
class and override the makeSound()
method.Aspect | Member Inner Class | Static Nested Class | Local Inner Class | Anonymous Inner Class |
---|---|---|---|---|
Associated with | An instance of the enclosing class | The outer class itself | A block, method, or constructor | No specific name, used for single-use implementation |
Access to Outer Members | Can access instance and static members | Can only access static members | Can access enclosing class members and final local vars | Can access enclosing class members and final local vars |
Can be Static | No | Yes | No | No |
Use Cases | When inner class logically belongs to the enclosing class | When class is a utility or belongs to outer class | When class is used within a method | When a one-time implementation is needed |
Java’s inner classes and anonymous inner classes provide a way to organize code, increase encapsulation, and enable more readable and maintainable code. Whether you need to create logically grouped classes, static utilities, or one-off implementations, inner classes offer versatile options for structuring Java programs effectively.