HOWTO · Java

Static Class in Java

This article introduces Java static classes.

On this page

Java does not allow a top-level class to be declared static. A class declared inside another class can be static; this is a static nested class. It can be instantiated without an instance of its enclosing class, and it can use the enclosing class’s static members. If you want a utility class that callers cannot construct through its public API, use a private constructor instead; that is a separate design pattern.

What Is a Static Nested Class in Java?

A static nested class is a member type declared with the static keyword inside another class. The static modifier means an instance of the nested class has no implicit reference to an enclosing-class object. It does not mean the nested class itself cannot be instantiated. Its type is accessed through the enclosing type, such as Container.Entry, and an instance method is called on an instance of that nested type.

A static nested class can access static members of its enclosing class, including private ones. It cannot refer to an enclosing instance’s fields or methods as though it had an enclosing object. It can do so when an enclosing object is explicitly supplied.

How to Declare and Use a Static Nested Class

Declare the member class with static, then use the enclosing type name to construct it. This complete example also shows access to an enclosing static field:

Run this example:

public class Container {
    private static int count = 3;

    public static class Entry {
        public int value() {
            return count;
        }
    }

    public static void main(String[] args) {
        Container.Entry entry = new Container.Entry();
        System.out.println(entry.value());
    }
}
3

Running the example prints 3. When adapting it, keep the nested class inside the enclosing class and qualify its type as Container.Entry outside Container. The Entry object is a normal instance, while count belongs to the enclosing class itself.

Static Nested Class vs. Inner Class

A non-static member class is commonly called an inner class. Constructing one requires an enclosing instance: create a Container object, then use container.new Inner(). An inner class instance can use the enclosing object’s instance members directly because it retains that association.

A static nested class has no such implicit association. To read an enclosing instance field, pass or otherwise obtain a Container object and access the field through that reference. Both kinds of nested classes can access members allowed by Java’s nested-type access rules; the key difference is whether an enclosing instance is automatically available.

How to Create a Non-Instantiable Utility Class

A utility class groups operations or constants that do not need per-object state. Put those members in a regular top-level class, mark appropriate members static, and add a private constructor so ordinary callers cannot invoke new from outside the class. For example, the pattern is public final class TextTools { private TextTools() {} public static String join(String first, String second) { return first + second; } }; call it as TextTools.join("static ", "utility").

The private constructor prevents ordinary external construction, but it does not turn TextTools into a static class; Java has no top-level static classes. Declaring the class final is optional and only prevents subclassing. Use it when that restriction is part of the design, not as a requirement for utility methods.

Common Misconceptions About Static Classes

A static nested class can be instantiated; static removes the implicit enclosing instance requirement. Its instance methods can use its own instance fields. The enclosing class name qualifies the nested type, while an object of the nested type is still needed to call its instance methods.

A static context cannot access an enclosing instance member by an unqualified name because no enclosing object is available automatically. It can access that member through an explicit object reference. Likewise, a private utility constructor prevents ordinary calls from outside the class, rather than making construction impossible under every circumstance. These distinctions separate Java’s nested-class syntax from the utility-class pattern.