Using Java, developers have the ability to define a class within another class. Such a class is called a Nested Class. Nested Classes are called Inner Classes if they were declared as non-static, if not, they are simply called Static Nested Classes. This page is to document and provide details with examples on how to use Java Nested and Inner Classes.
The Java Language Specification (JLS) classifies the different kinds of Java class as follows:
A top level class is a class that is not a nested class.
A nested class is any class whose declaration occurs within the body of another class or interface.
An inner class is a nested class that is not explicitly or implicitly declared static.
An inner class may be a non-static member class, a local class, or an anonymous class. A member class of an interface is implicitly static so is never considered to be an inner class.
In practice programmers refer to a top level class that contains an inner class as the "outer class". Also, there is a tendency to use "nested class" to refer to only to (explicitly or implicitly) static nested classes.
Note that there is a close relationship between anonymous inner classes and the lambdas, but lambdas are classes.
Top level classes are the "base case". They are visible to other parts of a program subject to normal visibility rules based on access modifier semantics. If non-abstract, they can be instantiated by any code that where the relevant constructors are visible based on the access modifiers.
Static nested classes follow the same access and instantiation rules as top level classes, with two exceptions:
private, which makes it inaccessible outside of its enclosing top level class.
privatemembers of the enclosing top-level class and all of its tested class.
This makes static nested classes useful when you need to represent multiple "entity types" within a tight abstraction boundary; e.g. when the nested classes are used to hide "implementation details".
Inner classes add the ability to access non-static variables declared in enclosing scopes:
final. (For Java 8 and later, they can be effectively final.)
The fact that an inner class instance can refer to variables in a enclosing class instance has implications for instantiation. Specifically, an enclosing instance must be provided, either implicitly or explicitly, when an instance of an inner class is created.