DevAcademia
C++C#CPythonJava
  • Java Basics

  • Java Introduction
  • Java Get Started
  • Java Syntax
  • Java Output
  • Java Comments
  • Java Variables
  • Java Data Types
  • Java Type Casting
  • Java Operators
  • Java Strings
  • Java If...Else
  • Java Switch Statement
  • Java Loops
  • Java Math
  • Java Arrays
  • Java Date
  • Java OOP

  • Java Classes/Objects
  • Java Class Attributes
  • Java Class Methods
  • Java Constructors
  • Java Destructors
  • Java this Keyword
  • Java Modifiers
  • Java Non Modifiers
  • Java Encapsulation
  • Java Packages & API
  • Java Inheritance
  • Java Polymorphism
  • Java Super Keyword
  • Java Inner Classes
  • Java Exception Handling
  • Java Abstraction
  • Java Interfaces
  • Java Enums
  • Java User Input
  • Java Quiz

  • Java Fundamentals Quiz
  • Java Basics

  • Java Introduction
  • Java Get Started
  • Java Syntax
  • Java Output
  • Java Comments
  • Java Variables
  • Java Data Types
  • Java Type Casting
  • Java Operators
  • Java Strings
  • Java If...Else
  • Java Switch Statement
  • Java Loops
  • Java Math
  • Java Arrays
  • Java Date
  • Java OOP

  • Java Classes/Objects
  • Java Class Attributes
  • Java Class Methods
  • Java Constructors
  • Java Destructors
  • Java this Keyword
  • Java Modifiers
  • Java Non Modifiers
  • Java Encapsulation
  • Java Packages & API
  • Java Inheritance
  • Java Polymorphism
  • Java Super Keyword
  • Java Inner Classes
  • Java Exception Handling
  • Java Abstraction
  • Java Interfaces
  • Java Enums
  • Java User Input
  • Java Quiz

  • Java Fundamentals Quiz

Loading Java tutorial…

Loading content
Java OOPTopic 53 of 59
←PreviousPrevNextNext→

Java Inner Classes

Introduction to Inner Classes

Inner classes (also called nested classes) are classes defined within another class. They are used to logically group classes that are only used in one place, increase encapsulation, and make code more readable and maintainable.

Java supports four types of nested classes:

1. Member inner classes

2. Static nested classes

3. Local inner classes

4. Anonymous inner classes

Types of Inner Classes

TypeDescriptionAccess Modifiers
Member Inner ClassDefined at the same level as instance variablesCan use any access modifier
Static Nested ClassDefined with static modifierCan use any access modifier
Local Inner ClassDefined inside a method or blockCannot use access modifiers
Anonymous Inner ClassDefined and instantiated simultaneously without a nameNo access modifier

Member Inner Class

A member inner class is defined at the member level of a class (same level as methods and instance variables). It has access to all members of the outer class, including private members.

Example
class Outer {
    private String outerField = "Outer field";
    
    class Inner {
        private String innerField = "Inner field";
        
        public void display() {
            System.out.println("Accessing outer field from inner class: " + outerField);
            System.out.println("Inner field: " + innerField);
        }
    }
    
    public void createInner() {
        Inner inner = new Inner();
        inner.display();
    }
}

public class MemberInnerClassExample {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.createInner();
        
        // Creating inner class from outside
        Outer.Inner inner = outer.new Inner();
        inner.display();
    }
}
Output
Accessing outer field from inner class: Outer field
Inner field: Inner field
Accessing outer field from inner class: Outer field
Inner field: Inner field

Static Nested Class

A static nested class is defined with the static modifier. It cannot access non-static members of the outer class directly.

Example
class Outer {
    private static String staticField = "Static field";
    private String instanceField = "Instance field";
    
    static class StaticNested {
        public void display() {
            System.out.println("Accessing static field: " + staticField);
            // Cannot access instanceField directly
            // System.out.println(instanceField); // Error
        }
    }
}

public class StaticNestedExample {
    public static void main(String[] args) {
        // Creating static nested class without outer instance
        Outer.StaticNested nested = new Outer.StaticNested();
        nested.display();
    }
}
Output
Accessing static field: Static field

Local Inner Class

A local inner class is defined within a method or block. It can only be instantiated within that method or block and can access final or effectively final local variables.

Example
class Outer {
    private String outerField = "Outer field";
    
    public void methodWithLocalClass() {
        final String localVar = "Local variable"; // Must be final or effectively final
        
        class LocalInner {
            public void display() {
                System.out.println("Outer field: " + outerField);
                System.out.println("Local variable: " + localVar);
            }
        }
        
        LocalInner local = new LocalInner();
        local.display();
    }
}

public class LocalInnerExample {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.methodWithLocalClass();
    }
}
Output
Outer field: Outer field
Local variable: Local variable

Anonymous Inner Class

An anonymous inner class is defined and instantiated at the same time without a explicit class name. It's commonly used for implementing interfaces or extending classes with small modifications.

Example
interface Greeting {
    void greet();
}

class AnonymousInnerExample {
    public static void main(String[] args) {
        // Anonymous class implementing Greeting interface
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("Hello from anonymous class!");
            }
        };
        
        greeting.greet();
        
        // Anonymous class extending Thread class
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("Thread running from anonymous class");
            }
        };
        
        thread.start();
    }
}
Output
Hello from anonymous class!
Thread running from anonymous class

Best Practices

- Use inner classes when they're logically part of the outer class and not needed elsewhere

- Prefer static nested classes when you don't need access to outer instance members

- Use anonymous classes for one-time implementations of interfaces or small extensions

- Be cautious with memory usage as non-static inner classes hold references to outer instances

- Consider using lambda expressions instead of anonymous classes for functional interfaces

Test your knowledge: Java Inner Classes
Quiz Configuration
4 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
Java OOPTopic 53 of 59
←PreviousPrevNextNext→