Java Nested and Inner Class

In this article, you will learn to work with nested and inner classes in Java with the help of examples.

In Java, you can define a class within another class. Such class is known as nested class.

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

There are two types of nested classes you can create in Java.

  • Non-static nested class (inner class)
  • Static nested class

Let's first look at non-static nested classes.


Non-Static Nested Class

Non-static nested class is a class within another class, where the class has access to members of the enclosing class (outer class). It is commonly known as inner class.

Since, inner class exists within the outer class (in order to instantiate an inner class, you must first instantiate the outer class).

Here’s example how you can declare Inner classes in Java.

Example 1: Inner class

class CPU {
    double price;
    class Processor{
        double cores;
        String manufacturer;
        double getCache(){
            return 4.3;
        }
    }
    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());
    }
}

When you run above program, the output will be:

Processor Cache = 4.3
Ram Clock speed = 5.5

In above program, the class CPU encapsulates two inner classes i.e. Processor and RAM. Since, the class RAM is inner class you can declared it as protected.

In the Main class, the instance of CPU is created at first. And in order to create the instance of Processor, the . (dot) operator is used.

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

Accessing Members of Outer Class within Inner Class

Like we discussed, inner classes can access the members of the outer class. This is possible using Java this keyword

Example 2: Accessing Members

public class Car {
    String carName;
    String carType;
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }
    private String getCarName() {
        return this.carName;
    }
    class Engine {
        String engineType;
        void setEngine() {
// Accessing carType property of Car
            if(Car.this.carType.equals("4WD")){
// Invoking method getCarName() of Car
                if(Car.this.getCarName().equals("Crysler")) {
                    this.engineType = "Bigger";
                } else {
                    this.engineType = "Smaller";
                }
            }else{
                this.engineType = "Bigger";
            }
        }
        String getEngineType(){
            return this.engineType;
        }
    }
}
public class CarMain {
    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());
    }
}

When you run above program, the output will be:

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

In above program, inside the Engine inner class, we used this keyword to get access to the member variable carType of outer class Car as:

Car.this.carType.equals("4WD)

This is possible even though the carType is a private member of Car class.

You can also see, we've used Car.this to access members of Car. If you had only used this instead of Car.this, then it would only represent members inside the Engine class.

Similarly, we've also invoked method getCarName() from Car using this keyword as:

Car.this.getCarName().equals("Crysler")

Here, getCarName() method is a private method of Car.


Static Inner Class

In Java, you can also define a nested class static. Such class is known as static nested class. However, they are not called static inner class.

Unlike inner class, static nested class cannot access the member variables of the outer class because static nested class doesn't require you to create an instance of outer class. Hence, no reference of the outer class exists with OuterClass.this.

So, you can create instance of static nested class directly like this:

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

Example 3: Static Inner Class

Public class MotherBoard {
    String model;
    public MotherBoard(String model) {
        this.model = model;
    }
    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());
    }
}

When you run the above program, the output will be:

Total Ports = 3

In the above program, we've declared static inner class USB using the keyword static.

You can also see, in the Main class, we directly created an instance of USB from MotherBoard with the . (dot) operator without creating an instance of Motherboard first.

MotherBoard.USB usb = new MotherBoard.USB();

Let's see what would happen, if you try to access the members of the outer class:


Example 4: Accessing members of Outer class inside Static Inner Class

public 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());
    }
}

When you run above program, you'll get an error:

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

This is because, no reference of outer class Motherboard is stored in Motherboard.this.


Key Points to Remember

  • Java treats inner class as a regular member of a class. They are just like methods and variables declared inside a class.
  • Since, inner class are members of outer class, you can apply any access modifiers like private, protected to your inner class which is not possible in normal classes.
  • Since Nested class is a member of its enclosing class Outer, you can use . (dot) notation to access Nested class and its members.
  • Using nested class will make your code more readable and provide better encapsulation.
  • Non-static nested classes (inner classes) have access to other members of the outer/enclosing class, even if they are declared private.

Recommended Reading

Java Access Modifiers

Java Static Keyword