English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java Basic Tutorial

Java Flow Control

Java Arrays

Java Object-Oriented (I)

Java Object-Oriented (II)

Java Object-Oriented (III)

Java Exception Handling

Java List (List)

Java Queue (Queue)

Java Map Collections

Java Set Collections

Java Input/Output (I/O)

Java Reader/Writer

Other Java Topics

Java Nested and Inner Classes

In this tutorial, you will learn about nested classes in Java and their types through examples.

In Java, you can define a class within another class. Such a class is called a nested class (嵌套类). For example,

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

You can create two types of nested classes using Java.

  • Non-static nested class (inner class)

  • Static nested class

Related Reading:

Let's first take a look at the non-static nested class.

Non-static nested class (inner class)

Non-static nested class is a class within another class. It has access to the members of the enclosing class (outer class). It is usually called inner class (inner class).

Since the inner class exists within the outer class, it is necessary to instantiate the outer class first in order to instantiate the inner class.

This is an example of how to declare an inner class in Java.

Example1: inner class

class CPU {
    double price;
    // Nested class
    class Processor{
        //Members of a nested class
        double cores;
        String manufacturer;
        double getCache(){
            return 4.3;
        }
    }
    //Nested protected class
    protected class RAM{
        //Members of a protected nested class
        double memory;
        String manufacturer;
        double getClockSpeed(){
            return 5.5;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        //Create an object of the external class CPU
        CPU cpu = new CPU();
       //Create an object of the inner class Processor using the external class
        CPU.Processor processor = cpu.new Processor();
        //Create an object of the inner class RAM using the external class CPU
        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

In the above program, there are two nested classes: Processor and RAM are inside the external class CPU:. We can declare the inner class as protected. Therefore, we have declared the RAM class as protected.

Inside the Main class

  • We first create an instance of the external class CPU named cpu.

  • Then, using an instance of the outer class, create an object of the inner class: 

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

Note: We use the dot (.) operator to create an instance of the inner class using the outer class.

Accessing the members of the outer class within an inner class

We can use the this keyword to access the members of the outer class. If you want to learn more about this keyword, please visitJava this keyword}. 

Example2: Access member

class Car {
    String carName;
    String carType;
    //Use constructor assignment
    public Car(String name, String type) {
        this.carName = name;
        this.carType = type;
    }
    // Private method
    private String getCarName() {
        return this.carName;
    }
    //Inner class
    class Engine {
        String engineType;
        void setEngine() {
           //Access the carType property of Car
            if(Car.this.carType.equals("4WD")){
                //Call the getCarName() method of Car
                if(Car.this.getCarName().equals("Crysler")) {
                    this.engineType = "Smaller";
                }
                    this.engineType = "Bigger";
                }
            }
                this.engineType = "Bigger";
            }
        }
        String getEngineType() {
            return this.engineType;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        //Create an object of the outer class Car
        Car car1 = new Car("Mazda", "8WD");
        //Create an object of the inner class using the outer class
        Car.Engine engine = car1.new Engine();
        engine.setEngine();
        System.out.println("8WD engine type = " + engine.getEngineType());
        Car car2 = new Car("Crysler", "4WD");
        Car.Engine c2engine = car2.new Engine();
        c2engine.setEngine();
        System.out.println("4WD engine type = " + c2engine.getEngineType());
    }
}

Output:

8WD engine type = Bigger
4WD engine type = Smaller

In the above program, we have an inner class named Engine in the outer class Car. Please note this line,

if(Car.this.carType.equals("4WD")) { ... }

We use the this keyword to access the variable carType of the outer class Car. You may have noticed that we use Car.this.carType instead of this.carType.

This is because if we do not mention the name of the outer class Car, then the this keyword will represent the member of the inner class.

Similarly, we also access the methods of the external class from the inner class.

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

It should be noted that although getCarName() is a private method, we can access it from the inner class.

Static nested class

In Java, we can also define a static (static) class in another class. This type is called a static nested class (static nested class). A static nested class is not called a static inner class.

Unlike inner classes, static nested classes cannot access the member variables of the external class. This is becauseStatic nested classYou do not need to create an instance of the external class.

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

Here, we createStatic nested classThe object. Therefore, we cannot use OuterClass.this to refer to the external class.

Example3: Static inner class

class MotherBoard {
   //Static nested class
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           return usb2 + usb3;
       }
   }
}
public class Main {
   public static void main(String[] args) {
       //Create an object of a static nested class
       //: Using the name of the external class
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = ", + usb.getTotalPorts());
   }
}

Output:

Total Ports = 3

In the above program, we created a static class named USB within the class MotherBoard. Note this line,

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

Here, we create a USB object using the name of the external class.

Now, let's see what happens if we try to access the members of an external class:

Example4: Accessing the members of an external class within a static inner class

class MotherBoard {
   String model;
   public MotherBoard(String model) {
       this.model = model;
   }
   //Static nested class
   static class USB{
       int usb2 = 2;
       int usb3 = 1;
       int getTotalPorts(){
           //Access the variable model of an external class
           if(MotherBoard.this.model.equals("MSI")) {
               return 4;
           }
           else {
               return usb2 + usb3;
           }
       }
   }
}
public class Main {
   public static void main(String[] args) {
       //Create an object of a static nested class
       MotherBoard.USB usb = new MotherBoard.USB();
       System.out.println("Total Ports = ", + usb.getTotalPorts());
   }
}

When we try to run the program, an error will occur:

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

This is because we did not use an object of the outer class to create an object of the inner class. Therefore, there is no reference stored in Motherboard.this of the outer class Motherboard.

Points to Remember

  • Java treats inner classes as regular class members. They are like methods and variables declared within a class.

  • Since the inner class is a member of the outer class, any access modifier (such as private, protected) can be applied to the inner class, which is not possible in a regular class.

  • Since the nested class is a member of the enclosing outer class, you can use the dot (.) notation to access the nested class and its members.

  • Using nested classes will make your code more readable and provide better encapsulation.

  • Non-static nested classes (inner classes) can access the outer class./Other members of the enclosed class, even if they are declared as private, are also accessible.