The term inner class is conventionally taken to mean "a nested class which requires an enclosing instance". However, the JLS states as follows:
8.1.3. Inner Classes and Enclosing Instances
[...]
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5).
[...]
An instance of an inner class whose declaration occurs in a static context has no lexically enclosing instances.
Also,
15.9.5. Anonymous Class Declarations
[...]
An anonymous class is always an inner class (§8.1.3); it is never
static
(§8.1.1, §8.5.1).
And it is well-known that an anonymous class may be declared in a static context:
class A { int t() { return 1; } static A a = new A() { int t() { return 2; } }; }
To describe it poignantly,
new A() {}
is a nested class without an enclosing instance, defined in a static context, but it is not a static nested class—it is an inner class.
Are we all assigning inappropriate meanings to these terms in day-to-day usage?
As a related point of interest, this historical specification document defines the term top-level as the opposite of inner:
Classes which are
static
class members and classes which are package members are both called top-level classes. They differ from inner classes in that a top-level class can make direct use only of its own instance variables.
Whereas in the common usage top-level is taken to be the opposite of nested.
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.
Inner classes are a security mechanism in Java. We know a class cannot be associated with the access modifier private, but if we have the class as a member of other class, then the inner class can be made private. And this is also used to access the private members of a class.
Unlike a class, an inner class can be private and once you declare an inner class private, it cannot be accessed from an object outside the class. Following is the program to create an inner class and access it.
In this situation the "not an enclosing class" error is due to incorrect use of this . this , within an instance method or constructor, refers to the current object. Using MainActivity. this is referring to the object MainActivity as if it were the current object but the current object is of type TestHandler .
The distinctions laid out in the question make perfect sense from the specification's standpoint:
an inner class has restrictions applied to it, which have nothing to do with the question of enclosing instances (it may not have static members, for example);
the concept of a static nested class is basically just about namespacing; these classes might rightfully be termed top-level, together with what we usually assume as top-level classes.
It just so happens that removing static
from a nested class declaration does two separate things at once:
We rarely think about inner as entailing restrictions; we only focus on the enclosing instance concern, which is much more visible. However, from the specification's viewpoint, the restrictions are a vital concern.
What we are missing is a term for a class requiring an enclosing instance. There is no such term defined by the JLS, so we have (unaware, it seems) hijacked a related, but in fact essentially different, term to mean that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With