ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

手作りネットプロトコル工房コミュの忘れ去られた初期化ブロック

  • mixiチェック
  • このエントリーをはてなブックマークに追加
class A {
  static LIST = new ArrayList<String>();
}

こうやって static のフィールドがあったとき、このオブジェクトの中身を初期化したいとする。 これが static フィールドでなければ、コンストラクタで初期化するのだけど ... static フィールドなので コンストラクタは呼び出せない。 どうすればいいのだろうか。

答えは簡単で

class A {
  static List<String> LIST = new ArrayList<String>();
  static {
    LIST.add( "A" );
    LIST.add( "B" );
    LIST.add( "C" );
  }
}

こうやって static 初期化ブロック( static initialization block ) を作ればいい。

ここまではいいのだ。 この間人の書いたソースを眺めていたら、こういうソースに出くわした。

class A {
  List<String> LIST = new ArrayList<String>();
  {
    LIST.add( "A" );
    LIST.add( "B" );
    LIST.add( "C" );
  }
}

ぎょっとした。 なんだこれは、と思った。
こんな書き方J2SEのソースを端から端まで眺めても出てこなかった。

調べたらこれは 初期化ブロック ( initialization block つうかそのままじゃん) といって 全てのコンストラクタの前に実行されるブロックなのだそうだ。 そんなものがあるとは知らなかった! これは面白い!

... でも これって使い道あるだろうか。 普通こういう初期化はワンライナーで書けるならその場に書いてしまうし、そうでなければ、コンストラクタに書けばいいだけの話だ。 コンストラクタからメソッドを呼び出せば継承も使える。 初期化ブロックは継承する方法が無いので、一瞬便利そうだけど、つかえないなぁ...。

今日プログラムを書いていて使い道を思いついた。 無名クラスだ。

TestClass c = new TestClass() {
  List<String> LIST = new ArrayList<String>();
  void test() {
  }
}

無名クラスでは コンストラクタの定義が出来ない。 これにはいつも悩まされていたのだが、こんな場合でも この初期化ブロックは利用できる。

TestClass c = new TestClass() {
  List<String> LIST = new ArrayList<String>();
  {
    LIST.add( "A" );
    LIST.add( "B" );
    LIST.add( "C" );
  }
  void test() {
  }
}

これは使える...。

あとは static でない final フィールドの初期化を行う時、コンストラクタで super を呼び出す前に 親クラスのフィールドを参照したい時に、相互参照になってどうやってもコンパイルが通らなくなってしまう時がある。 ( 例が思い出せない。) こういう場合も初期化ブロックで対処できると思う。

コメント(0)

mixiユーザー
ログインしてコメントしよう!

手作りネットプロトコル工房 更新情報

手作りネットプロトコル工房のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング