java中嵌套类有四种,现在举例说明: 静态成员类 非静态成员类 局部类 匿名类 。
class Outer {
int age = 20;
String name = "outer";
static class Inner {
int age = 10;
String name = "inner";
}
}
静态内部类, 调用方法 Outer.Inner inner = new Outer.Inner(); 生成一个内部类的对象
class Outer {
int age = 20;
String name = "outer";
class Inner {
int age = 10;
String name = "inner";
}
}
非静态内部类, 调用方法 Outer.Inner inner = new Outer().new Inner(); 生成对象,注意与上面的静态类的生成方法有何不同
class Outer {
int age = 20;
String name = "outer";
public void test(){
class Inner{
int age = 20;
String name = "outer";
public void testPrint(){
System.out.println(" age " + age + " name " + name);
}
}
Inner inner = new Inner();
inner.testPrint();
}
}
局部类,调用方法 Outer outer = new Outer(); outer.test(); 局部类范围更小,更像是局部的辅助类
class Outer {
int age = 20;
String name = "outer";
public void test(){
System.out.println(" age " + age + " name " + name);
}
}
匿名类, 调用方法 new Outer().test();
匿名类我们平常可能经常用到,不如给一个方法传递一个对象,可以直接new一个,好处就是用完就回收,比较节省内存,这种常用带一次调用的场景;局部类这种方法,平时用到的不多,算是小范围的辅助类,一般都是定义在方法里,用完就完了;
静态成员类 和 非静态成员类 这两种用的比较多,重点说一下。静态成员类可以理解为是一个单独的类,只是恰好定义在一个类的内部而已,仅此而已。它不会对它外部的类持有对象引用而消耗大量内存或者造成内存泄漏。这种类一般都是作为辅助类,和外部类一起用才有意义。比如常见的 Builder 模式、 枚举 等等。 非静态成员类比着静态的少了个 static 的修饰,但会发现,创建对象的方法不一样, Outer.Inner inner = new Outer.Inner(); Outer.Inner inner = new Outer().new Inner(); 还是有差别的, 非静态内部类的实例会对外部类造成引用,会产生关联关系,当外部类调用内部类的方法时,关系就会被建立,这种内存的消耗是持续的。 非静态内部类中不允许出现静态变量和静态方法的声明,static 只能用在常量的声明上; 静态内部类则无此现在。
例如, HashMap 中 的
public final Spliterator<V> spliterator() {
return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0);
}
static final class ValueSpliterator<K,V>
extends HashMapSpliterator<K,V>
implements Spliterator<V> {
ValueSpliterator(HashMap<K,V> m, int origin, int fence, int est,
int expectedModCount) {
super(m, origin, fence, est, expectedModCount);
}
}
static class HashMapSpliterator<K,V> {
final HashMap<K,V> map;
HashMapEntry<K,V> current; // current entry
int index; // current index, modified on advance/split
int fence; // one past last index
int est; // size estimate
int expectedModCount; // for comodification checks
HashMapSpliterator(HashMap<K,V> m, int origin,
int fence, int est,
int expectedModCount) {
this.map = m;
this.index = origin;
this.fence = fence;
this.est = est;
this.expectedModCount = expectedModCount;
}
}
创建 迭代器时,迭代器内部要对Map的 HashMapEntry,HashMapEntry 继承 Map.Entry, 即会产生大量的 Entry 对象,如果以上没有static 的修饰,会造成每个entry都包含一个map的引用,造成极大的空间和时间的浪费。
平常如果用内部类,更多的是是静态的,基本无内存泄漏的危险。静态和非静态各有好处,如果拿不准用哪个,那就选 静态 的吧。