Java 的各种内部类

Java 中有多种内部类,其实平时经常用到,这里整理一下,用到比较多都是Android的例子。

1.成员内部类
这是最常见的一种内部类,大部分为了方便而写在一个文件里面的类基本都属于这样的,
优点:使用灵活,不用写太多的文件
缺点:在外部创建内部类实例需要先创建一个Container的实例

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

故比较适合只在当前类里使用的,比如某个自定义的 View

public class OuterLayout extends FrameLayout{

    private class InnerLayout extends View {
        // 这就是一个成员内部类
        public InnerLayout(Context context) {
            super(context);
        }
    }
   //省略...
}

2. 静态内部类

OuterClass.InnerClass inner = new OuterClass.InnerClass();

优点:同样是使用方便,和1相比,避免内存泄露
缺点:不能灵活的使用非静态的实例,所在的 OuterClass 的很多类成员属性都不能直接使用。
使用场景:类内部使用的java Bean常用

关于泄露
非静态内部类的对象默认包含了它的Container的引用,比如:

class A{
   class B{   }
}

B的对象中默认有一个A的引用,垃圾回收的时候,如果处理不当,有可能导致A的对象不能被回收,导致内存泄漏。

换成静态内部类后,默认引用就没有了,比如:

class A{
  static class B{  }
}

泄露栗子:

public class ExampleActivity extends Activity{

    private static LeakClass leakInstance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(leakInstance == null) {
            leakInstance = new LeakClass();
        }
    }

    private class LeakClass {
        //这个内部类创建后就持有了Activity的引用
    }
}

leakInstance由于是一个内部类,持有了activity的引用,此时如果activity被销毁重建,那么原先的activity就会被leakInstance持有,不能被回收。
所以建议改成

private static class LeakClass

3. 局部内部类
在方法内部创建的类,生命周期只存在于方法周期内,少用

4. 匿名内部类
优点:使用简单,方便快捷,实现接口的实例比较方便
缺点:使用太多的话会造成代码可读性差

栗子:

OnClickListener l = new OnClickListener() {
        @Override
        public void onClick(View v) {
            //匿名内部类
            //可用于对接口的简单实例化 ,通常只使用一次
        }
  };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章