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) {
            //匿名內部類
            //可用於對接口的簡單實例化 ,通常只使用一次
        }
  };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章