Shiklo Programming
EN
  • English
  • Español
  • Português
  • Deutsch
  • Français
  • 日本語
  • हिन्दी

Java Inner Classes

A class can be declared inside another class. This is useful when a small helper class only makes sense together with its outer class: a Node inside a linked list, a Builder inside the class it builds, an Entry inside a map. Java has four kinds of classes inside classes, and you will meet all of them in real code.

Static nested classes

A static nested class is like a normal class that just lives inside another one. You create it with Outer.Nested:

class Shop {
    static class Item {
        final String name;
        final double price;

        Item(String name, double price) {
            this.name = name;
            this.price = price;
        }
    }

    static double total(Item... items) {
        double sum = 0;
        for (Item i : items) {
            sum += i.price;
        }
        return sum;
    }
}

public class Main {
    public static void main(String[] args) {
        Shop.Item tea = new Shop.Item("Tea", 120);
        Shop.Item cup = new Shop.Item("Cup", 80);
        System.out.println(Shop.total(tea, cup));
    }
}
Output
200.0

The Item... parameter uses the varargs from Method Parameters.

Inner classes

A nested class without static is an inner class. Each inner object belongs to an outer object and can use its fields, even private ones:

class Counter {
    private int count = 0;

    class Clicker {
        void click() {
            count++;
            System.out.println("Count is now " + count);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Counter c = new Counter();
        Counter.Clicker a = c.new Clicker();
        Counter.Clicker b = c.new Clicker();
        a.click();
        b.click();
        a.click();
    }
}
Output
Count is now 1
Count is now 2
Count is now 3

Both clickers belong to the same counter, so they increase the same count. The unusual c.new Clicker() says which outer object the inner one belongs to.

Local classes

A class can even be declared inside a method. It is then only usable in that method, and it can use the method's variables as long as they do not change:

public class Main {
    public static void main(String[] args) {
        String greeting = "Hi";

        class Greeter {
            String greet(String name) {
                return greeting + ", " + name + "!";
            }
        }

        Greeter g = new Greeter();
        System.out.println(g.greet("Tara"));
        System.out.println(g.greet("Dev"));
    }
}
Output
Hi, Tara!
Hi, Dev!

Anonymous classes

An anonymous class is a class without a name, declared and created in one expression. It is used for one-off implementations of an interface or an abstract class:

interface Discount {
    double apply(double price);
}

public class Main {
    public static void main(String[] args) {
        Discount festival = new Discount() {
            @Override
            public double apply(double price) {
                return price * 0.8;
            }
        };
        System.out.println(festival.apply(1000));
    }
}
Output
800.0

Because Discount has only one abstract method, the same thing can be written much more shortly with a lambda: Discount festival = price -> price * 0.8;. The Lambda topic shows how, and lambdas have replaced most anonymous classes in modern code.

Practice exercises

  1. Make a static nested class Point inside a class Geometry and a static method that returns the distance between two points.
  2. Give a class Playlist a private list of song names and an inner class Player that prints the next song.
  3. Implement an interface Shape with an anonymous class whose area() returns 42.