Java Inner Classes

Java Inner Classes (Nested Classes)

In Java, it is also possible to nest classes (a class within a class). The purpose of nested classes is to group classes that belong together, which makes your code more readable and maintainable.

To access the inner class, you must create an object of the outer class, and then create an object of the inner class.


Types of Nested Classes

There are two main types of nested classes in Java:

  1. Non-static nested classes (Inner Classes):
    • Member Inner Class
    • Anonymous Inner Class
    • Local Inner Class
  2. Static nested classes

Member Inner Class Example

A non-static inner class (or member inner class) is a class created within another class. It has access to all members (attributes and methods) of the outer class, even the private ones.

Inner Class Example

class OuterClass {
  int x = 10;

class InnerClass { public int myInnerMethod() { // Can access attributes of the outer class return x; } } }

public class Main { public static void main(String[] args) { OuterClass myOuter = new OuterClass(); OuterClass.InnerClass myInner = myOuter.new InnerClass(); System.out.println(myInner.myInnerMethod()); } }


Static Nested Class

A static class created inside a class is called a static nested class. Unlike an inner class, a static nested class cannot access the non-static members of the outer class. It can be accessed without creating an object of the outer class.

Static Nested Class Example

class OuterClass {
  static int x = 10;

static class InnerClass { int y = 5; } }

public class Main { public static void main(String[] args) { // Note how we don't need an object of OuterClass OuterClass.InnerClass myInner = new OuterClass.InnerClass(); System.out.println(myInner.y + OuterClass.x); } }


Local Inner Classes

A local inner class is a class defined within a block, which is usually a method. Local classes belong to the block they are defined in, and they are not members of the enclosing class. They can access the final or effectively final local variables of the enclosing block.

Local Inner Class Example

class OuterClass {
  void myMethod() {
    final int num = 23;
    // Local Inner Class
    class LocalInner {
      public void print() {
        System.out.println("Local variable: " + num);
      }
    }
    // Instantiate and use the local inner class within the method
    LocalInner inner = new LocalInner();
    inner.print();
  }
}

public class Main { public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.myMethod(); } }


Anonymous Inner Classes

An anonymous inner class is a class without a name that is instantiated at the same time it is declared. It is used when you need to use a local class only once. It usually extends an existing class or implements an interface.

Anonymous Inner Class Example

interface Greeting {
  void greet();
}

public class Main { public static void main(String[] args) { // Creating an anonymous inner class that implements the Greeting interface Greeting myGreeting = new Greeting() { public void greet() { System.out.println("Hello from an anonymous inner class!"); } }; myGreeting.greet(); } }


Shadowing

If a declaration of a type (such as a member variable or a parameter name) in a particular scope (such as an inner class) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. You cannot refer to a shadowed declaration by its name alone.

Shadowing Example

class OuterClass {
  int x = 0; // Outer class variable
  class InnerClass {
    int x = 1; // Inner class variable
    void printVariables(int x) {
      System.out.println("Method parameter x = " + x);
      System.out.println("Inner class field this.x = " + this.x);
      System.out.println("Outer class field OuterClass.this.x = " + OuterClass.this.x);
    }
  }
}

public class Main { public static void main(String[] args) { OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = outer.new InnerClass(); inner.printVariables(2); } }


Exercise

?

Can a static nested class access non-static members of its outer class?