From the Java Tutorial:

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

Static nested classes are accessed using the enclosing class name:

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

see: Java Tutorial - Nested Classes

For completeness note that there is also such a thing as an inner class without an enclosing instance:

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.

Answer from Martin on Stack Overflow
🌐
Oracle
docs.oracle.com › javase › tutorial › java › javaOO › nested.html
Nested Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.
Top answer
1 of 16
1934

From the Java Tutorial:

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

Static nested classes are accessed using the enclosing class name:

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

see: Java Tutorial - Nested Classes

For completeness note that there is also such a thing as an inner class without an enclosing instance:

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.

2 of 16
687

The Java tutorial says:

Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

In common parlance, the terms "nested" and "inner" are used interchangeably by most programmers, but I'll use the correct term "nested class" which covers both inner and static.

Classes can be nested ad infinitum, e.g. class A can contain class B which contains class C which contains class D, etc. However, more than one level of class nesting is rare, as it is generally bad design.

There are three reasons you might create a nested class:

  • organization: sometimes it seems most sensible to sort a class into the namespace of another class, especially when it won't be used in any other context
  • access: nested classes have special access to the variables/fields of their containing classes (precisely which variables/fields depends on the kind of nested class, whether inner or static).
  • convenience: having to create a new file for every new type is bothersome, again, especially when the type will only be used in one context

There are four kinds of nested class in Java. In brief, they are:

  • static class: declared as a static member of another class
  • inner class: declared as an instance member of another class
  • local inner class: declared inside an instance method of another class
  • anonymous inner class: like a local inner class, but written as an expression which returns a one-off object

Let me elaborate in more details.


Static Classes

Static classes are the easiest kind to understand because they have nothing to do with instances of the containing class.

A static class is a class declared as a static member of another class. Just like other static members, such a class is really just a hanger on that uses the containing class as its namespace, e.g. the class Goat declared as a static member of class Rhino in the package pizza is known by the name pizza.Rhino.Goat.

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

Frankly, static classes are a pretty worthless feature because classes are already divided into namespaces by packages. The only real conceivable reason to create a static class is that such a class has access to its containing class's private static members, but I find this to be a pretty lame justification for the static class feature to exist.


Inner Classes

An inner class is a class declared as a non-static member of another class:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

    private void jerry() {
        Goat g = new Goat();
    }
}

Like with a static class, the inner class is known as qualified by its containing class name, pizza.Rhino.Goat, but inside the containing class, it can be known by its simple name. However, every instance of an inner class is tied to a particular instance of its containing class: above, the Goat created in jerry, is implicitly tied to the Rhino instance this in jerry. Otherwise, we make the associated Rhino instance explicit when we instantiate Goat:

Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();

(Notice you refer to the inner type as just Goat in the weird new syntax: Java infers the containing type from the rhino part. And, yes new rhino.Goat() would have made more sense to me too.)

So what does this gain us? Well, the inner class instance has access to the instance members of the containing class instance. These enclosing instance members are referred to inside the inner class via just their simple names, not via this (this in the inner class refers to the inner class instance, not the associated containing class instance):

public class Rhino {

    private String barry;

    public class Goat {
        public void colin() {
            System.out.println(barry);
        }
    }
}

In the inner class, you can refer to this of the containing class as Rhino.this, and you can use this to refer to its members, e.g. Rhino.this.barry.


Local Inner Classes

A local inner class is a class declared in the body of a method. Such a class is only known within its containing method, so it can only be instantiated and have its members accessed within its containing method. The gain is that a local inner class instance is tied to and can access the final local variables of its containing method. When the instance uses a final local of its containing method, the variable retains the value it held at the time of the instance's creation, even if the variable has gone out of scope (this is effectively Java's crude, limited version of closures).

Because a local inner class is neither the member of a class or package, it is not declared with an access level. (Be clear, however, that its own members have access levels like in a normal class.)

If a local inner class is declared in an instance method, an instantiation of the inner class is tied to the instance held by the containing method's this at the time of the instance's creation, and so the containing class's instance members are accessible like in an instance inner class. A local inner class is instantiated simply via its name, e.g. local inner class Cat is instantiated as new Cat(), not new this.Cat() as you might expect.


Anonymous Inner Classes

An anonymous inner class is a syntactically convenient way of writing a local inner class. Most commonly, a local inner class is instantiated at most just once each time its containing method is run. It would be nice, then, if we could combine the local inner class definition and its single instantiation into one convenient syntax form, and it would also be nice if we didn't have to think up a name for the class (the fewer unhelpful names your code contains, the better). An anonymous inner class allows both these things:

new *ParentClassName*(*constructorArgs*) {*members*}

This is an expression returning a new instance of an unnamed class which extends ParentClassName. You cannot supply your own constructor; rather, one is implicitly supplied which simply calls the super constructor, so the arguments supplied must fit the super constructor. (If the parent contains multiple constructors, the “simplest” one is called, “simplest” as determined by a rather complex set of rules not worth bothering to learn in detail--just pay attention to what NetBeans or Eclipse tell you.)

Alternatively, you can specify an interface to implement:

new *InterfaceName*() {*members*}

Such a declaration creates a new instance of an unnamed class which extends Object and implements InterfaceName. Again, you cannot supply your own constructor; in this case, Java implicitly supplies a no-arg, do-nothing constructor (so there will never be constructor arguments in this case).

Even though you can't give an anonymous inner class a constructor, you can still do any setup you want using an initializer block (a {} block placed outside any method).

Be clear that an anonymous inner class is simply a less flexible way of creating a local inner class with one instance. If you want a local inner class which implements multiple interfaces or which implements interfaces while extending some class other than Object or which specifies its own constructor, you're stuck creating a regular named local inner class.

🌐
DEV Community
dev.to › dhanush9952 › java-inner-classes-and-nested-classes-39a6
Java Inner Classes and Nested Classes - DEV Community
October 27, 2024 - Use Inner Classes for Encapsulation: Keep functionality closely tied to an outer class within an inner class to improve encapsulation. Static Nested Classes for Utility: When you need a helper class that doesn’t need access to an instance of the outer class, go with a static nested class.
🌐
W3Schools
w3schools.com › java › java_inner_classes.asp
Java Inner Class (Nested 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, create an object of the outer class, and then create an object of the inner class:
🌐
Programiz
programiz.com › java-programming › nested-inner-class
Java Nested and Inner Class (With Examples)
There are two types of nested classes you can create in Java. ... Let's first look at non-static nested classes. A non-static nested class is a class within another class. It has access to members of the enclosing class (outer class). It is commonly known as inner class.
🌐
GeeksforGeeks
geeksforgeeks.org › java › difference-between-static-and-non-static-nested-class-in-java
Difference Between Static and Non Static Nested Class in Java - GeeksforGeeks
July 23, 2025 - In the Java programming language, you can not make a top-level class static. You can only make nested classes either static or non-static. If you make a nested class non-static then it also referred to as Inner class.
🌐
Medium
medium.com › codex › finer-points-of-java-the-difference-between-nested-inner-and-anonymous-classes-2c7ca0ac4f60
Finer points of Java: the difference between nested, inner and anonymous classes | by Alonso Del Arte | CodeX | Medium
June 1, 2022 - A nested class is simply any class defined within another class. A nested inner class is a class that has special access to the members of the enclosing class.
🌐
Quora
quora.com › What-is-the-difference-between-an-inner-class-and-a-nested-class-in-Java
What is the difference between an inner class and a nested class in Java? - Quora
Answer (1 of 4): It's a really good question most of us get confused in it. I am trying to answer it in a very easy manner. In below example of Nested class, nestedClassLevel2 is inside nestedClassLevel1 and which is inside mainClass1. Here the classes are maintaining the parent-child relationshi...
Find elsewhere
🌐
Medium
medium.com › javarevisited › do-you-know-nested-and-inner-classes-in-java-latest-b270e0988091
Do You Know Nested and Inner Classes in Java? | by BaseCS101 | Javarevisited | Medium
February 4, 2024 - Whereas Non-static nested classes are called inner classes. The Static Nested Class cannot refer directly to instance fields or methods defined in its enclosing class(i.e. outer class) but it can only use them through an object reference of ...
🌐
Rice
clear.rice.edu › comp310 › JavaResources › inner_class.html
Nested and Inner Classes
Nested classes are typically used simply to organize classes and avoid name conflicts. Inner classes declartions are not marked static and thus exist at the instance level of a the outer class.
🌐
Coderanch
coderanch.com › t › 371162 › java › nested-classes
nested vs inner classes (Java in General forum at Coderanch)
here is an example: This allows you to set up event responses to a component without haveing to create a separate class to handle the job. It is static, but can only be used by the method where it is defined An inner class is simple a second class defined inside a primary class like this: ...
🌐
Coderanch
coderanch.com › t › 396123 › java › nested
nested vs. inner (Beginning Java forum at Coderanch)
All inner classes are also considered nested. I'm guessing you're asking if it's better to use inner classes or static nested classes. I'd say that if you don't need to access an outer "this" reference then static nested is simpler, and easier for others (especially beginners) to understand.
🌐
Tutorialspoint
tutorialspoint.com › java › java_innerclasses.htm
Java - Inner classes
In Java, just like methods, variables of a class too can have another class as its member. Writing a class within another is allowed in Java. The class written within is called the nested class, and the class that holds the inner class is called ...
🌐
Medium
medium.com › @utkarshtewari80 › java-difference-between-inner-class-and-static-nested-class-a4ae774c6ef0
Java: Difference Between Inner Class and Static Nested Class | by Utkarshtewari | Medium
December 30, 2023 - A Nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.
🌐
Baeldung
baeldung.com › home › java › core java › inner classes vs. subclasses in java
Inner Classes vs. Subclasses in Java | Baeldung
January 8, 2024 - Inner classes are a form of Nested Classes in Java and are defined within the boundaries of another host class.
🌐
Blogger
javarevisited.blogspot.com › 2012 › 12 › inner-class-and-nested-static-class-in-java-difference.html
Inner class and nested Static Class in Java with Example
August 24, 2021 - Inner class and nested static class ... Java terminology, If you declare a nested class static, it will called nested static class in Java while non-static nested classes are simply referred as Inner Class....
🌐
Medium
medium.com › @rohitpatil3898 › inner-classes-in-java-8fce1868891f
Inner classes in JAVA. Class inside a class is called as inner… | by Rohit Raghunath Patil | Medium
October 12, 2024 - 5. A normal inner class can access both static and non-static members of the outer class directly but from the static nested class, we can access only static members. Can We Create Object of Static Nested Class Outside Outer Class?
🌐
Belief Driven Design
belief-driven-design.com › nested-classes-in-java-814dff35bef
Nested Classes in Java | belief driven design
June 29, 2020 - Or we might end up with a java.io.NotSerializableException. Inner classes have the advantage of having a deeper connection to their enclosing class, including full access to all of its members. But this connection can lead to non-obvious memory retention. The enclosing class can’t be ...
🌐
Javatpoint
javatpoint.com › java-inner-class
Java Inner Classes (Nested Classes)
Java inner class or nested class with member inner class, anonymous inner class, local inner class and java static nested class.
Top answer
1 of 4
33

Joshua Bloch in Item 22 of his book "Effective Java Second Edition" tells when to use which kind of nested class and why. There are some quotes below:

One common use of a static member class is as a public helper class, useful only in conjunction with its outer class. For example, consider an enum describing the operations supported by a calculator. The Operation enum should be a public static member class of the Calculator class. Clients of Calculator could then refer to operations using names like Calculator.Operation.PLUS and Calculator.Operation.MINUS.

One common use of a nonstatic member class is to define an Adapter that allows an instance of the outer class to be viewed as an instance of some unrelated class. For example, implementations of the Map interface typically use nonstatic member classes to implement their collection views, which are returned by Map’s keySet, entrySet, and values methods. Similarly, implementations of the collection interfaces, such as Set and List, typically use nonstatic member classes to implement their iterators:

// Typical use of a nonstatic member class
public class MySet<E> extends AbstractSet<E> {
    ... // Bulk of the class omitted

    public Iterator<E> iterator() {
        return new MyIterator();
    }

    private class MyIterator implements Iterator<E> {
        ...
    }
}

If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration, making it a static rather than a nonstatic member class.

2 of 4
12

You are correct in assuming that the attribute access available to non-static inner classes leads to high coupling, hence to lower code quality, and (non-anonymous and non-local) inner classes should generally be static.

Design implications of decision to make inner class non-static are laid out in Java Puzzlers, Puzzle 90 (bold font in below quote is mine):

Whenever you write a member class, ask yourself, Does this class really need an enclosing instance? If the answer is no, make it static. Inner classes are sometimes useful, but they can easily introduce complications that make a program difficult to understand. They have complex interactions with generics (Puzzle 89), reflection (Puzzle 80), and inheritance (this puzzle). If you declare Inner1 to be static, the problem goes away. If you also declare Inner2 to be static, you can actually understand what the program does: a nice bonus indeed.

In summary, it is rarely appropriate for one class to be both an inner class and a subclass of another. More generally, it is rarely appropriate to extend an inner class; if you must, think long and hard about the enclosing instance. Also, prefer static nested classes to non-static. Most member classes can and should be declared static.

If you're interested, a more detailed analysis of Puzzle 90 is provided in this answer at Stack Overflow.


It is worth noting that above is essentially an extended version of the guidance given in Java Classes and Objects tutorial:

Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.

So, the answer to the question you asked in other words per tutorial is, the only convincing reason to use non-static is when access to an enclosing instance's non-public fields and methods is required.

Tutorial wording is somewhat broad (this may be the reason why Java Puzzlers make an attempt to strengthen it and narrow it down). In particular, directly accessing enclosing instance fields has never been really required in my experience - in the sense that alternative ways like passing these as constructor / method parameters always turned easier to debug and maintain.


Overall, my (quite painful) encounters with debugging inner classes directly accessing fields of enclosing instance made strong impression that this practice resembles use of global state, along with known evils associated with it.

Of course, Java makes it so that damage of such a "quasi global" is contained within enclosing class, but when I had to debug particular inner class, it felt like such a band aid didn't help to reduce pain: I still had to keep in mind "foreign" semantic and details instead of fully focusing on analysis of a particular troublesome object.


For the sake of completeness, there may be cases where above reasoning doesn't apply. For example, per my reading of map.keySet javadocs, this feature suggests tight coupling and as a result, invalidates arguments against non-static classes:

Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa...

Not that above would somehow make involved code easier to maintain, test and debug mind you, but it at least could allow one to argue that complication matches / is justified by intended functionality.