views:

4152

answers:

7

Hi All,

I was looking at the Java code for LinkedList and noticed that it made use of a static nested class Entry.

public class LinkedList<E> ... {
...

 private static class Entry<E> { ... }

}

What is the reason for using a static nested class, rather than an normal inner class?

The only reason I could think of, was so that Entry doesn't have access to instance variables, so from an OOP point of view it has better encapsulation.

But I thought there might be other reasons, maybe performance. Anyone have any thoughts?

Note. I hope I have got my terms correct, I would have called it a static inner class, but I think this is wrong: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

+6  A: 

To my mind, the question ought to be the other way round whenever you see an inner class - does it really need to be an inner class, with the extra complexity and the implicit (rather than explicit and clearer, IMO) reference to an instance of the containing class?

Mind you, I'm biased as a C# fan - C# doesn't have the equivalent of inner classes, although it does have nested types. I can't say I've missed inner classes yet :)

Jon Skeet
C# has inner classes... http://www.csharphelp.com/archives/archive113.html
chills42
I could be wrong, but that looks to me like an example of a static nested class, not an inner class. They even specify in the example that they don't have access to instance variables on the surrounding class in the nested class.
ColinD
Yup, Colin's right - C# doesn't have inner classes, it has nested classes. Mind you, a static nested class in C# isn't the same as a static nested class in Java :)
Jon Skeet
A: 

One of the reasons for static vs. normal have to do with classloading. You cannot instantiate an inner class in the constructor of it's parent.

PS: I've always understood 'nested' and 'inner' to be interchangeable. There may be subtle nuances in the terms but most Java developers would understand either.

Mark Renouf
A: 

I don't know about performance difference, but as you say, static nested class is not a part of an instance of the enclosing class. Seems just simpler to create a static nested class unless you really need it to be an inner class.

It's a bit like why I always make my variables final in Java - if they're not final, I know there's something funny going on with them. If you use an inner class instead of a static nested class, there should be a good reason.

+17  A: 

The Sun page you link to has some key differences between the two:

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.
...

Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

There is no need for LinkedList.Entry to be top-level class as it is only used by LinkedList (there are some other interfaces that also have static nested classes named Entry, such as Map.Entry - same concept). And since it does not need access to LinkedList's members, it makes sense for it to be static - it's a much cleaner approach.

As Jon Skeet points out, I think it is a better idea if you are using a nested class is to start off with it being static, and then decide if it really needs to be non-static based on your usage.

matt b
+3  A: 

Well, for one thing, non-static inner classes have an extra, hidden field that points to the instance of the outer class. So if the Entry class weren't static, then besides having access that it doesn't need, it would carry around four pointers instead of three.

As a rule, I would say, if you define a class that's basically there to act as a collection of data members, like a "struct" in C, consider making it static.

+1  A: 

Simple example :

package test;

public class UpperClass {
public static class StaticInnerClass {}

public class InnerClass {}

public static void main(String[] args) {
 // works
 StaticInnerClass stat = new StaticInnerClass();
 // doesn't compile
 InnerClass inner = new InnerClass();
}
}

If non-static the class cannot be instantiated exept in an instance of the upper class (so not in the example where main is a static function)

Vinze
+3  A: 

There are non-obvious memory retention issues to take into account here. Since a non-static inner class maintains an implicit reference to it's 'outer' class, if an instance of the inner class is strongly referenced, then the outer instance is strongly referenced too. This can lead to some head-scratching when the outer class is not garbage collected, even though it appears that nothing references it.

Leigh