nested classes : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)

nested classes
Nested classes are a feature of Java version 1.1 or later where nested classes are allowed to be defined inside enclosing classes. There are two types: inner and static. Anonymous inner classes let you define new unnamed classes and instantiate objects with them, right in the middle of methods.
The Six Types of Classes Accessing methods and Fields
Learning More Variable Visibility in Inner and Outer Classes
The Basics Variable Visibility In Anonymous Classes
Instantiating Variable Visibility In Local Classes
Extending Nested Interfaces
When To Use Inner Classes Gotchas
Scope Learning More
Inheritance Links

The Six Types of Classes

There are six different, sometimes overlapping, classifications of classes:
  1. top level classes: not nested, but possibly sharing a *.java file.
  2. nested classes: like Russian dolls (either static or inner).
  3. static classes: no associated outer class instance.
  4. inner classes: with an associated outer class instance.
  5. anonymous classes: unnamed inner class defined in the middle of a method (where static init blocks and instance init blocks count as methods).
  6. local classes: named inner class defined in the middle of a method. (where static init blocks and instance init blocks count as methods). Just to keep you on your toes, some programmers us the term local class to include anonymous class.
Are the classes sharing a source file nested or distinct? Separate ones are called top-level classes. Nested classes are called, logically enough, nested. There are two flavours of nested classes, static classes (which can be allocated independently of any particular outer class object), and inner classes which are always allocated in conjunction with some particular instance of the outer class object. Anonymous inner classes don’t have name, or rather they have a name generated by the compiler. There is no such thing as an anonymous static class. A local class is given a name, and is defined right in the middle of an instance method. You may never have heard of local classes; I have never seen one used in practice, but they do exist in theory. I would avoid them simply on the grounds of avoiding baffling others reading your code. One possible use might be to define an Iterator used twice in a method but nowhere else. Logically, anonymous classes are also local, though the term local class in the JLS (Java Language Specification) refers only to named local classes not anonymous classes.

Properly, the term inner classes only applies to the fourth, fifth and sixth types. For the remainder of this essay, I will attempt to use the term inner class only in that sense.

Just to make matters even more confusing, many programmers refer to both static nested classes and inner instance classes as inner classes, even though properly speaking inner implies non-static i.e. instance. I tend to use the term nested only for static nested classes, which is not quite kosher either.

The word static is so badly abused in Java. It has so many meanings, none of them anything like its meaning in ordinary English. The term static class is especially misleading. Static classes can be instantiated just like any other. They have both static and instance fields. They were probably called static just to avoid creating another reserved keyword.

The Basics

The first thing to understand is that nested classes are just classes. Nearly everything you know about classes still applies.

Inner classes have no keyword to mark them, other than class. Anonymous inner classes don’t even have that. What makes them nested is the way the {} marking the beginning and end of the class nest with other classes.

static nested classes have the marking static class.

You can define an anonymous class, create an anonymous instance of it, and pass it as a parameter to some method all in one (albeit very long) line. Anonymous classes were originally intended primarily for use by code generators. If you want to write really hard to follow code, you can nest inner classes within inner classes and make them anonymous if you

Here

Instantiating

Inside the enclosing class, you can instantiate inner classes with the ordinary syntax. Only outside the outer class
// instantiating an inner class from inside the outer class.
Inner in = new Inner();

// instantiating an inner class from outside the outer class.
Outer out = new Outer();
Outer.Inner in = out.new Inner();

You can instantiate an static nested class like this:

Extending Inner or Static Nested Classes

Here is how to allocate and extend an inner class or nested static class.

When To Use Inner Classes

Inner classes are ugly. They have no identifying inner or nested keyword to alert you to their presence. It is so easy to miss them buried. You have to look at the {…} very carefully to decide if they are truly inner classes or just non public classes sharing the same source file, i.e. top level classes. So why would you want them? If you find that you are passing a ton of stuff in the constructor to a class and that class is only used by one other class, inner classes may come to the rescue, by giving direct reference to all the outer class’s fields. Similarly if you find you are doing a huge amount of referencing of the outer class’s fields, think of inner classes. Inner classes can also take a snapshot in time of the final local variables of an outer class’s calling method. To develop intuition, try coding both ways and see which comes out cleaner.

Scope

Allowed Scopes for Various classes
Type of Class Possible scopes Notes
top level classes public default At most one top level class per *.java file can be public. Note that top level classes cannot be private (since which class would they be private to?). Further, they cannot be protected. Why I don’t know.
static classes public protected default private default refers to the package level scope you get by leaving off a scope modifier.
inner classes public protected default private Note that inner classes are not necessarily private. Unless you make an inner class private it is also known outside the outer class.
anonymous classes none Such classes are have no name, hence have no scope. They are known thus only within the statement in which they are defined.
local classes none Such classes are known only within the method/block in which they are defined.

Inheritance

The rules of what can inherit from what are complicated, but logical.
Nested Class Inheritance Rules
  Subclass
Superclass top level class nested static class inner class anonymous inner class local inner class
top level class
nested static class
in same outer class
nested static class
in different outer class
inner class
in same outer class
inner class
in different outer class
anonymous inner class
local inner class
In the table above, inheritance is ok, provided the non-final superclass is in scope and has a non-private constructor in scope.

Accessing methods and Fields

In inner classes, (anonymous or named), you can refer to this of the outer class via MyOuterClass. this. You can refer to the outer class’s methods by myOuterInstanceMethod() or MyOuterClass.this. myOuterInstanceMethod(). You can access the outer class’s static methods with myOuterStaticMethod() or MyOuterClass. myOuterStaticMethod().

You might imagine that inner classes are merely a scope mechanism, that they are independent classes, visible only to the outer class. Not so. For every inner class object there must exist an associated outer class object. You can’t create inner class objects without first creating an outer class object. You must create inner class objects in instance methods so that this implicitly gives you the corresponding outer class object.

On the other hand, if you declare the nested class static, that class can be independently instantiated. Since the class is not associated with any particular instance of the outer class, you may not use MyOuterClass. this.myOuterInstanceMethod() to access its instance methods. You could use someInstance. myOuterInstanceMethod() though, and of course you can access the outer class’s static methods with myOuterStaticMethod() or MyOuterClass. myOuterStaticMethod()

If you are an assembler programmer, the following explanation may be helpful. If not, please ignore the rest of this paragraph. It will just confuse you. Inner class constructors get passed a hidden parameter, a reference to the outer class object that created them. static nested classes don’t have this hidden parameter. This is analogous to the way instance methods have hidden this parameter, where static methods do not.

The reverse rules for how outer classes get at the field and methods of nested ones are obvious. Outer classes access inner class and nested class fields and methods the same way they would any other independent class.

Variable Visibility In Inner and Outer Classes

The rules for communication between inner and outer classes are complicated. The best way to explain it is with example showing all allowed possibilities that instance inner and static nested classes (I wish there were inner and nested keywords!) have for accessing the corresponding The basic rule is static nested classes may access only static outer variables and methods. This is logical, since there is no corresponding instance object. Further, there is no requirement for variables accessed to be final.

Variable Visibility In Anonymous Classes

The goofy, anonymous inner classes defined in the middle of a method, in addition to the other communication possibilities, have limited access to the local variables in the method from which it was spawned. I don’t mean that local variables passed to the anonymous constructor are restricted. You can pass any value at all, both final and non-final, local or non-local to the anonymous class constructor.

The local variables that must be final in order to be accessed, live in the method that instantiates and encloses the anonymous class. The access we are talking about is direct use of the variable names from inside the methods of the anonymous class.

Again, let

The rule is anonymous inner classes may only access final local variables of the enclosing method. Why? Because the inner class’s methods may be invoked later, long after the method that spawned it has terminated, e.g. by an AWT (Advanced Windowing Toolkit) event. The local variables are long gone. The anonymous class then must work with flash frozen copies of just the ones it needs squirreled away covertly by the compiler in the anonymous inner class object.

You might ask, why do the local variables have to be final? Could not the compiler just as well take a copy of non-final local variables, much the way it does for a non-final parameters? If it did so, you would have two copies of the variable. Each could change independently, much like caller and callee’s copy of a parameter, however you would use the same syntax to access either copy. This would be confusing. So Sun insisted the local be final. This makes irrelevant that there are actually two copies of it.

The ability for an anonymous class to access the caller’s final local variables is really just syntactic sugar for automatically passing in some local variables as extra constructor parameters. The whole thing smells to me of diluted eau de kludge.

Variable Visibility In Local Classes

Local classes behave the same an anonymous classes. They can see the final local variables of the calling method.

Nested Interfaces

Interfaces can be nested in an analogous way to classes. Just replace the keyword class with interface. The JLS explains how
work. You can also define an interface
. You can read more about them in the
and
.

Gotchas

  1. The good news first: Top level classes sharing a source file are handled no differently than ones that each get their own independent source file.
  2. Inner classes are not permitted to have static methods or fields. That is not quite true. They are allowed static final compile time constants, which are treated as if there were literals. Sorry I don’t know why the restriction. Nobody I have asked knows why. This is probably the single most annoying fact about nested classes. If inner classes need statics, they have to get the outer class to hold them, or you have to use static nested classes or you have to inherit the static fields. Oddly, inner classes are permitted to extend classes that do have static methods and fields.

    static methods in an anonymous class could not be called from outside the anyonymous class, which perhaps explains part of it.

    Mark Space offers this explanation for the restriction. Conceptually, non-static member classes, local and anonymous classes are all a part of the enclosing class. Thus they should be using the enclosing class for any static members.

    For future potential optimization, preventing static members might allow future JVMs (Java Virtual Machines) to take some short cuts with inner class objects, and initialize the objects more quickly or otherwise do away with one or more steps involved in creating their class object. Since static members weren’t needed (since they could be promoted to an enclosing class (however, not enclosing object)), they were proscribed.

  3. There is no such thing as an anonymous static nested class, or static local class.
  4. There is no such thing as a top level static class.
  5. An enum is a species of class, so it can be a public class, a top level default class or a nested static class. Inner class enums are considered static even if you don’t use the static keyword. An enum follows the same scope and visibility rules as any other class. enums can have static or instance fields and methods that apply to the enum as a whole. However enum constants, since they are implemented as inner classes, may not have static fields or methods, just instance fields and methods.

Learning More


Dick Baldwin has written an essay explaining the various sorts of nested classes.

This page is posted
on the web at:

http://mindprod.com/jgloss/nestedclasses.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\nestedclasses.html
logo
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.
Blog
IP:[65.110.21.43]
Your face IP:[54.161.133.166]
You are visitor number