有时候为了避免内存泄露,使用静态内部类来取代非静态内部类,为什么呢?

解决方案 »

  1.   

    非静态内部类的对象默认包含了它的Container的引用,比如:
    class A{
       class B{   }
    }B的对象中默认有一个A的引用,垃圾回收的时候,如果处理不当,有可能导致A的对象不能被回收,导致内存泄漏。
      

  2.   

    换成静态内部类后,默认引用就没有了,比如:
    class A{
      static class B{  }
    }
    B的对象中就没有对A对象的引用。
      

  3.   

    你要一个静态内部类(题外话:static的不叫内部类,叫:nested class)实例的时候,你并不需要一个外部类的实例(Enclosing Instance),比如:class T {
    static class Nested {
    void sayHello() {
    System.out.println("hello");
    }
    }
    }class C {
        public static void main(String... args) {  
         new T.Nested().sayHello(); //不需要外部类T的实例,这里T只是一个类Nested的限定名称的一部分
        } 
    }内部类(非static的nested class)就不一样了,你要实例化一个内部类,必须要有一个外部类的实例,比如:class T {
    class Nested {
    void sayHello() {
    System.out.println("hello");
    }
    }
    }class C {
        public static void main(String... args) {  
         new T().new Nested().sayHello(); // 外部类T的实例 new T()是必须的
        } 
    }如果你的内部类中并不需要外部类的实例变量,实例方法的话,那么其实你只需要内部类的实例就够了,但是又必须得有个外部类的实例,虽然你用不到。
    如果你有很多内部类的实例,是由不同的外部类的实例创建的,虽然没有其他的对象引用你的外部类对象,但内部类引用了(内部类对象在创建的时候虚拟机会自动把外部类对象的实例传进去作为一个实例变量保存),所以GC不能够回收这写外部类对象,这样就有可能造成内存泄露。
    所以呢,既然你并不需要外部类的实例变量,实例方法,你加上一个static关键字,就不许要外部类对象了。
      

  4.   

    非静态内部类与外部类相互引用,jvm不知道何时去gc,就会出现泄露。
    静态内部类就不会影响外部类的destroy