What is the main difference between an inner class and a static nested class in Java? Does design / implementation play a role in choosing one of these?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
Here is key differences and similarities between Java inner class and static nested class.
Hope it helps!
Inner class
Associated with instance of enclosing class so to instantiate it first needs an instance of outer class (note new keyword place):
Cannot define any static members itself
Static nested class
Cannot access outer class instance methods or fields
Not associated with any instance of enclosing class So to instantiate it:
Similarities
Why Use Nested Classes?
According to Oracle documentation there're several reasons (full documentation):
The following is an example of
static nested class
andinner class
:OuterClass.java
OuterClassTest:
The instance of the inner class is created when instance of the outer class is created. Therefore the members and methods of the inner class have access to the members and methods of the instance (object) of the outer class. When the instance of the outer class goes out of scope, also the inner class instances cease to exist.
The static nested class doesn't have a concrete instance. It's just loaded when it's used for the first time (just like the static methods). It's a completely independent entity, whose methods and variables doesn't have any access to the instances of the outer class.
The static nested classes are not coupled with the outer object, they are faster, and they don't take heap/stack memory, because its not necessary to create instance of such class. Therefore the rule of thumb is to try to define static nested class, with as limited scope as possible (private >= class >= protected >= public), and then convert it to inner class (by removing "static" identifier) and loosen the scope, if it's really necessary.
I think, the convention that is generally followed is this:
However, few other points to remembers are:
Top level classes and static nested class are semantically same except that in case of static nested class it can make static reference to private static fields/methods of its Outer [parent] class and vice versa.
Inner classes have access to instance variables of the enclosing instance of the Outer [parent] class. However, not all inner classes have enclosing instances, for example inner classes in static contexts, like an anonymous class used in a static initializer block, do not.
Anonymous class by default extends the parent class or implements the parent interface and there is no further clause to extend any other class or implement any more interfaces. So,
new YourClass(){};
meansclass [Anonymous] extends YourClass {}
new YourInterface(){};
meansclass [Anonymous] implements YourInterface {}
I feel that the bigger question that remains open which one to use and when? Well that mostly depends on what scenario you are dealing with but reading the reply given by @jrudolph may help you making some decision.
Nested class: class inside class
Types:
Difference:
Non-static nested class [Inner class]
In non-static nested class object of inner class exist within object of outer class. So that data member of outer class is accessible to inner class. So to create object of inner class we must create object of outer class first.
Static nested class
In static nested class object of inner class don't need object of outer class, because the word "static" indicate no need to create object.
If you want to access x, then write the following inside method
There is a subtlety about the use of nested static classes that might be useful in certain situations.
Whereas static attributes get instantiated before the class gets instantiated via its constructor, static attributes inside of nested static classes don't seem to get instantiated until after the class's constructor gets invoked, or at least not until after the attributes are first referenced, even if they are marked as 'final'.
Consider this example:
Even though 'nested' and 'innerItem' are both declared as 'static final'. the setting of nested.innerItem doesn't take place until after the class is instantiated (or at least not until after the nested static item is first referenced), as you can see for yourself by commenting and uncommenting the lines that I refer to, above. The same does not hold true for 'outerItem'.
At least this is what I'm seeing in Java 6.0.