Inner Classes in Java
A static nested class is a class declared inside another class with the static modifier, and it is part of the static structure of its containing class.
Why Place One Class Inside Another
Most Java classes you have written so far probably sit at the top level of a file, each one standing on its own. Java also allows a class to be declared inside the body of another class. When that happens, the inner class is called a nested class. This article focuses on one particular kind of nested class: the static nested class, which carries the static modifier in its declaration.
The usual reason for placing one class inside another is organization. A helper type that only makes sense in the context of a larger type can be kept next to that larger type, so the code describing one concept lives together. The way a nested class is placed changes how it is named, referred to, and used, and that naming rule is the main skill this article builds.
Anatomy of a Static Nested Class
A static nested class is a class declared inside another class with the static modifier, and it is part of the static structure of its containing class.
The declaration of a static nested class looks almost identical to the declaration of any other class. Two things are added. First, the class is written inside the body of another class. Second, the keyword static appears as part of its declaration. Nothing else about the way the class is written needs to change.
Predicting the Name Each Location Needs
Before reading the rule, commit to a prediction. The source uses a class called WireFrameModel that contains a static nested class called Line. Ask yourself: when code sits inside WireFrameModel, and when code sits outside it, does the name used for Line stay the same?
What do you think happens?
Code outside WireFrameModel needs to refer to the nested class Line. Which name must it use?
Reveal answer
WireFrameModel.Line
Outside its containing class, the nested class must be referred to by its full name: the containing class name, a period, and the nested class name. Inside the containing class, the nested class can be used in the usual way.
Tracing Names Inside the Containing Class
The source describes WireFrameModel, a set of lines in three-dimensional space and the kind of model used to represent three-dimensional objects in graphics programs. Its nested class Line represents one line, stored as two endpoints. The example below is an original illustration with a different containing class, so the naming rule can be checked on fresh code. Trace which name appears inside the containing class and which name appears in the main method.
public class Library {
static class Book {
String title;
Book(String title) {
this.title = title;
}
}
public static void main(String[] args) {
Book b = new Book("Dune");
System.out.println(b.title);
}
}- 1The class Library is the outer class. Its body contains the declaration of Book.
- 2The keyword static in static class Book makes Book a static nested class.
- 3Inside main, which is part of Library, the line new
Book("Dune")uses the simple name Book, because the code is inside the containing class. - 4The program prints the title stored in the object, which is Dune.
- Library is the containing (outer) class
- static class Book is the static nested class, declared inside Library's body
- Book is used by its simple name inside Library, where objects are created in the usual way
DuneThe key point is where the code sits. The simple name Book works here only because the reference is inside Library. The name is not changed by the nested class itself; the location of the reference decides which name is required.
Reaching In From Outside the Class
A name for a static nested class is built from two pieces joined by a period. The first piece is the name of the class in which the nested class is declared. The second piece is the name of the nested class itself. The result is the full name, and it is the name a program must use whenever it refers to the nested class from outside its containing class. In the source's example, the full name is WireFrameModel.Line.
// in a separate class, outside Library
Book b = new Book("Dune");The simple name Book is used outside the containing class, so the reference does not follow the full-name rule and the program breaks at this line.
// in a separate class, outside Library
Library.Book b = new Library.Book("Dune");The full name Library.Book is used, so the reference names the nested class correctly from outside its containing class.
The Static Structure of the Outer Class
The phrase part of the static structure matters. A static nested class belongs to the containing class itself, in the same way that a static member variable belongs to its class rather than to any single object created from it. So the nested class is not something each object of the outer class carries around. It is attached to the class as a whole.
The diagram shows the containment. WireFrameModel holds other members, and it also holds the static nested class Line. Line belongs to WireFrameModel as a class-level part of it, which is why the full name WireFrameModel.Line is the name that identifies it from outside.
Mistakes in Naming a Nested Class
Common mistake Using the simple name of the nested class from outside its containing class
What it looks likeBook b = new Book("Dune"); written in a separate class
Why it failsOutside the containing class, the nested class must be referred to by its full name.
Do this insteadLibrary.Book b = new Library.Book("Dune");Common mistake Reversing the two parts of the full name
What it looks likeBook.Library used to refer to the nested class
Why it failsThe full name is the containing class name, then a period, then the nested class name.
Do this insteadLibrary.Book
Common mistake Assuming the full name is required everywhere
What it looks likeWriting Library.Book b = new Library.Book("Dune"); inside LibraryWhy it failsThe full name rule applies to references from outside the containing class. Inside the containing class, the nested class can be used in the usual way.
Do this insteadInside Library, write Book b = new Book("Dune");
Finding the Line That Breaks
Read the three lines below. Each refers to the static nested class Book from the Library example. Decide which line will not compile when it sits outside the Library class, and explain the rule that makes it fail. Lines are numbered for reference.
Line 1: Library.Book first = new Library.Book("Emma");
Line 2: Book second = new Book("Emma");
Line 3: Library.Book third = new Book("Emma");Hints
- Ask whether each line is outside Library, and whether it uses the full name.
- Line 3 mixes the two forms. Check each name in it separately.
Key Takeaways
- A static nested class is a class declared inside another class with the static modifier, and it is part of the static structure of its containing class.
- Inside its containing class, a static nested class can be used to create objects in the usual way.
- Outside its containing class, the nested class must be referred to by its full name: the containing class name, a period, and the nested class name, as in
WireFrameModel.Line. - The nested class belongs to the class itself, in the same way that a static member variable belongs to the class rather than to individual objects.