1. java内部类不设置成静态,实例化的时候显得奇怪
普通内部类在实例化时必须先有外部类对象,例如
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
静态内部类则可以直接实例化,例如
Outer.Inner inner = new Outer.Inner();
java内部类设置成静态在使用上更方便,尤其是作为工具类或辅助类时(Builder 模式,如 StringBuilder、Map.Builder)。
2. java内部类不设置成静态,实例化的时候会导致内存泄漏
内存泄漏通俗来讲就是藕断丝连,然而藕断丝连并没有褒贬,但是内存泄漏是我们不愿看见的。举个不好的例子,即我们通常说的父债子还。如果一个烂赌的男人背负了巨额债务,即便是这位烂赌的男人死去了,讨债方会继续向这位烂赌的男人的后代讨债,想象一下这位烂赌的男人的后代的人生将会是多么的悲惨,对他们来说,这就是“内存泄漏”,即本该消亡的东西,却因为一些关联,仍有一部分不能消亡。如果这位烂赌的男人没有后代,或者他的后代早就和他断绝了关系,那么他背负的巨额债务也会随着男人的消亡而消亡。
普通的内部类(非静态)会隐式持有外部类的引用,因此必须依附于外部类对象存在。静态内部类则不持有外部类对象的引用,可以直接通过 Outer.Inner 的形式使用,不需要创建外部类对象。好处: 减少内存消耗(不会意外持有外部类的引用,避免内存泄漏);使用上更灵活,可以像独立类一样使用。
3. java内部类不设置成静态,成员变量管理起来比较混乱
当外部类和内部类拥有相同的成员变量时,使用起来是比较麻烦的,比如下面的代码:
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
运行结果是
x = 23
this.x = 1
ShadowTest.this.x = 0
4. java内部类不设置成静态,也有好处
可以直接访问父类的成员变量。如果把前面的烂赌的男人背负了巨额债务换成上进的男人积累了亿万家产,那么他的后代将会继承他的全部家产。对他的后代来讲,是非常有益的。