Static nested class in Java, why?

2019-01-01 10:07发布

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 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. What might it be?

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

13条回答
何处买醉
2楼-- · 2019-01-01 10:09

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 :)

查看更多
余欢
3楼-- · 2019-01-01 10:12

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.

查看更多
低头抚发
4楼-- · 2019-01-01 10:13

static nested class is just like any other outer class, as it doesn't have access to outer class members.

Just for packaging convenience we can club static nested classes into one outer class for readability purpose. Other than this there is no other use case of static nested class.

Example for such kind of usage, you can find in Android R.java (resources) file. Res folder of android contains layouts (containing screen designs), drawable folder (containing images used for project), values folder (which contains string constants), etc..

Sine all the folders are part of Res folder, android tool generates a R.java (resources) file which internally contains lot of static nested classes for each of their inner folders.

Here is the look and feel of R.java file generated in android: Here they are using only for packaging convenience.

/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found.  It
 * should not be modified by hand.
 */

package com.techpalle.b17_testthird;

public final class R {
    public static final class drawable {
        public static final int ic_launcher=0x7f020000;
    }
    public static final class layout {
        public static final int activity_main=0x7f030000;
    }
    public static final class menu {
        public static final int main=0x7f070000;
    }
    public static final class string {
        public static final int action_settings=0x7f050001;
        public static final int app_name=0x7f050000;
        public static final int hello_world=0x7f050002;
    }
}
查看更多
浮光初槿花落
5楼-- · 2019-01-01 10:13

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.

查看更多
余生请多指教
6楼-- · 2019-01-01 10:19

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.

查看更多
孤独寂梦人
7楼-- · 2019-01-01 10:21

From http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html:

Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.

查看更多
登录 后发表回答