Static Methods and Class-Level Members
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 a Class Inside Another Class
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 reason a programmer would place one class inside another is usually a matter of organization. A helper type that only makes sense in the context of a larger type can be kept next to that larger type, so that the code describing one concept lives together. Before going further, try to commit to a prediction: when one class is placed inside another, does the name you use to refer to the inner class change depending on where your code sits? The rest of this article shows how that placement changes the way the inner class is named, referred to, and used.
Tracing Where the Name Must Change
The source uses a class called WireFrameModel that contains a static nested class called Line. A wireframe model is a set of lines in three-dimensional space, the kind of model used to represent three-dimensional objects in graphics programs. The WireFrameModel class holds other members, and it also contains the static nested class Line. That Line class represents one line, stored as two endpoints: one with coordinates x1, y1, z1 and the other with coordinates x2, y2, z2.
- The nested class Line is declared inside the body of
WireFrameModel. - The static keyword appears in the declaration of Line.
- Code inside
WireFrameModeluses the plain name Line to create an object.
Trace the program as you read it. Every place where the code stays inside WireFrameModel can use the short name Line. The question to track is what happens when code reaches into WireFrameModel from the outside. The name required changes at that boundary, and that boundary is the main thing this article asks you to watch for.
What Makes a Nested Class Static
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. The class is written inside the body of another class, and the keyword static appears as part of its declaration. Nothing else about the way the class is written needs to change.
The phrase part of the static structure matters. The source makes an analogy with static member variables. A static variable belongs to its class rather than to any single object created from that class. In the same way, a static nested class belongs to the containing class itself. It is not something each object of the outer class carries around. It is attached to the class as a whole.
Read the diagram as a containment relationship, not a list of objects. Line is not drawn beneath any particular WireFrameModel object. It is drawn beneath the class WireFrameModel itself, which reflects the source's point that the nested class is part of the static structure of its containing class.
Building the Full Name
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 called the full name, and it is the name that a program must use whenever it refers to the nested class from outside its containing class. For the source's example, the full name is WireFrameModel.Line.
Read the anatomy strip from left to right. All three tokens are required from outside the containing class: the outer class name, the period, and the nested class name. Dropping the outer class name, or the period, leaves the compiler without a way to locate the nested class from where the code sits.
Writing the full name for an outside reference
A separate class named Demo, in the same package, wants to create a Line object. Line is the static nested class inside WireFrameModel. What must Demo write?
- 1Identify the containing class
Line is declared inside
WireFrameModel, soWireFrameModelis the outer class. - 2Join the two names with a period
The full name is the outer class name, then a period, then the nested class name:
WireFrameModel.Line. - 3Use the full name in the declaration and creation
Demo writes
WireFrameModel.Line edge = newWireFrameModel.Line(); because Demo sits outsideWireFrameModel.
The reference from outside must use WireFrameModel.Line, not the plain name Line.
Following a Reference From Inside and Outside
The following small program is an original illustration, not taken from the source. It uses a different containing class, Canvas, with a static nested class named Point. Read the two files and notice which name appears inside the containing class and which name appears in the other class. The first file is Canvas.java.
- Point is declared inside Canvas with the static modifier.
- Inside Canvas, the plain name Point is used to declare and create the object.
- The main method is also inside Canvas, so the short name still works.
The second file is Demo.java. It is a different class, so the code now stands outside Canvas. Two lines show the two possibilities. One uses the full name and one uses the plain name.
- Canvas.Point is the full name, built from the outer class name, a period, and the nested class name.
- The line Point q = new
Point(); uses the plain name from outside Canvas, which is the mistake this article is about. - The compiler rejects the plain name in Demo, so the program does not compile until that line is corrected.
What do you think happens?
In Demo.java, which line will the compiler reject?
Reveal answer
Point q = new Point();
Outside its containing class, a static nested class must be referred to by its full name, Canvas.Point. The plain name Point is not enough in Demo, so that line is the one that breaks the program.
Notice the contrast. Canvas.java uses the plain name Point throughout, and that works because the code sits inside the containing class. Demo.java uses the full name for the valid reference and fails on the plain name. The rule is not about what the class is called. It is about where the reference is written.
Naming Mistakes That Break Compilation
Common mistake Using the plain nested class name from outside the containing class
What it looks likePoint q = new Point(); written inside a class named Demo
Why it failsOutside its containing class, the nested class must be referred to by its full name, so the compiler cannot find Point from Demo.
Do this insteadWrite Canvas.Point q = new Canvas.Point(); in Demo.Common mistake Leaving out the period or the outer class name in the full name
What it looks likeWriting Point alone, or writing CanvasPoint with no period
Why it failsThe full name is made of the containing class name, a period, and the nested class name. Each of the three parts is needed.
Do this insteadUse the complete form Outer.Nested, such as WireFrameModel.Line.
Common mistake Assuming the short name works everywhere once it works inside the containing class
What it looks likeUsing Line in a separate file after it compiled inside WireFrameModel
Why it failsThe required name depends on where the code sits, not on whether the nested class exists.
Do this insteadCheck whether the reference is inside the containing class. If it is outside, use the full name.
Common mistake Confusing the nested class with a top-level class that happens to share its name
Practice Predicting the Name
A class called Garage contains a static nested class called Vehicle. Another class called Parking, in the same package, needs to declare a variable of type Vehicle. Before you write the line, predict what the declaration must look like. Then check whether the line compiles if written with the plain name. Finally, state which line would be the one the compiler points to if the plain name is used.
Hints
- Ask first whether the code sits inside Garage or outside it.
- The full name is the outer class name, a period, then the nested class name.
- The mistake breaks on the line where the plain name Vehicle is used from outside Garage.
Explain, in your own words, why WireFrameModel.Line works from outside the class while Line alone does not. Mention the word static in your answer and say what it attaches the nested class to.
Hints
- Refer to the analogy with static member variables.
- The nested class is part of the static structure of
WireFrameModel, not of any single object.
Key Takeaways
- A static nested class is a class declared inside another class with the static modifier, and it belongs to the static structure of its containing class.
- The containing class is called the outer class. For example, Line is nested inside
WireFrameModel. - Inside its containing class, a nested class can be used in the usual way, with its plain name.
- Outside its containing class, the nested class must be referred to by its full name: the outer class name, a period, and the nested class name, as in
WireFrameModel.Line. - Predicting a compile error starts with asking where the reference is written, then checking whether the plain name is used outside the containing class.