Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Industrial programming >> Java

Mastering Java Nested and Inner Classes: Types, Examples, and Best Practices

Java Nested and Inner Classes

Discover how Java’s nested classes enhance encapsulation, improve readability, and enable powerful inner‑class patterns.

In Java you can declare a class inside another class—this is called a nested class. For instance:

class OuterClass {
    // ...
    class NestedClass {
        // ...
    }
}

There are two main flavors of nested classes:

Recommended reading:

Non‑Static Nested Class (Inner Class)

An inner class resides within an outer class and can freely access the outer class’s members, even private ones. Because it is tied to an instance of the outer class, you must instantiate the outer class first.

Example 1: Inner Class

class CPU {
    double price;
    // inner class
    class Processor{
        double cores;
        String manufacturer;
        double getCache(){
            return 4.3;
        }
    }
    // protected inner class
    protected class RAM{
        double memory;
        String manufacturer;
        double getClockSpeed(){
            return 5.5;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        CPU cpu = new CPU();
        CPU.Processor processor = cpu.new Processor();
        CPU.RAM ram = cpu.new RAM();
        System.out.println("Processor Cache = " + processor.getCache());
        System.out.println("Ram Clock speed = " + ram.getClockSpeed());
    }
}

Output:

Processor Cache = 4.3
Ram Clock speed = 5.5

Here, Processor and RAM are nested within CPU. The RAM class is declared protected, demonstrating that inner classes can use any Java access modifier.

In Main, we first instantiate the outer class CPU, then create inner‑class instances via the outer instance:

CPU.Processor processor = cpu.new Processor;
CPU.RAM ram = cpu.new RAM();

Tip: The dot (.) operator is used to bind an inner‑class instance to its outer instance.

Accessing Outer Class Members from an Inner Class

Inner classes can reference the outer class’s members through the this keyword prefixed with the outer class name, e.g., Car.this.carType. This syntax is necessary when the inner class has its own this context.

Example 2: Interacting with the Outer Class

class Car {
    String carName;
    String carType;
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }
    private String getCarName() {
        return this.carName;
    }
    // inner class
    class Engine {
        String engineType;
        void setEngine() {
            if(Car.this.carType.equals("4WD")){
                if(Car.this.getCarName().equals("Crysler")) {
                    this.engineType = "Smaller";
                } else {
                    this.engineType = "Bigger";
                }
            } else {
                this.engineType = "Bigger";
            }
        }
        String getEngineType(){
            return this.engineType;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Car car1 = new Car("Mazda", "8WD");
        Car.Engine engine = car1.new Engine();
        engine.setEngine();
        System.out.println("Engine Type for 8WD= " + engine.getEngineType());
        Car car2 = new Car("Crysler", "4WD");
        Car.Engine c2engine = car2.new Engine();
        c2engine.setEngine();
        System.out.println("Engine Type for 4WD = " + c2engine.getEngineType());
    }
}

Output:

Engine Type for 8WD= Bigger
Engine Type for 4WD = Smaller

Even though getCarName() is private, the inner class can invoke it because it resides within the same outer class.

Static Nested Class

A static nested class does not require an instance of the outer class to be created. Consequently, it cannot directly access non‑static members of the outer class. It is created using the outer class’s name:

OuterClass.NestedClass obj = new OuterClass.NestedClass();

Example 3: Static Nested Class

class MotherBoard {
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           return usb2 + usb3;
       }
   }
}
public class Main {
   public static void main(String[] args) {
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = " + usb.getTotalPorts());
   }
}

Output:

Total Ports = 3

Example 4: Attempting to Access Outer Members in a Static Nested Class

class MotherBoard {
   String model;
   public MotherBoard(String model) {
       this.model = model;
   }
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           if(MotherBoard.this.model.equals("MSI")) {
               return 4;
           } else {
               return usb2 + usb3;
           }
       }
   }
}
public class Main {
   public static void main(String[] args) {
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = " + usb.getTotalPorts());
   }
}

Running this code produces:

error: non-static variable this cannot be referenced from a static context

This error occurs because the static nested class cannot reference MotherBoard.this without an outer instance.

Key Takeaways


Java

  1. Java Classes and Objects: A Practical Guide
  2. Java Abstract Classes and Methods: A Comprehensive Guide
  3. Understanding Java Nested Static Classes: Usage, Differences, and Examples
  4. Mastering Java Anonymous Inner Classes: Definition, Syntax, and Practical Examples
  5. Mastering Java’s ObjectInputStream: A Comprehensive Guide
  6. Mastering Java ObjectOutputStream: Serialization, Methods, and Practical Examples
  7. Mastering Java’s PrintStream Class: Print, Println, and Printf Explained
  8. Master Java: Understanding Objects, Classes, and Core OOP Concepts
  9. Java Inner Classes Explained: Design, Syntax, and Practical Uses
  10. Java 9: Simplify Anonymous Inner Classes with the Diamond Operator