staic初期化子

staic初期化子

Javaのプログラムをリファクタリング中。Singletonパターンを適用したクラスにシステム全体で使うようなデータベースを持たせようと思ったのだが、どのように初期化するのかで詰まってしまった。以前似たようなな状況でにstatic初期化子を使ったのでまた調べてみた。参考ページはJavaの常識・非常識

  • static初期化子は、クラスがメモリ上にロードされるとき、一回だけ実行される。その後、
  • インスタンス化されても実行されるない。

static初期化子は、それが定義されているクラスがクラス・ローダにロードされるとき、さらに詳しく言えば、そのクラスのインスタンスが最初に生成される際、コンストラクタが呼び出される前に実行される。 つまり自分の場合はSingletonパターンを適用したクラスについてこのようなコードを書けば尾言い訳だ。

final class Singleton {
  private static final Singleton instance = new Singleton();
  private Singleton(){};
  
  static{
	// static 初期化子
        //データベースの初期化処理
  }

  public static Singleton getInstance(){
    return Singleton.instance;
  }

}

静的初期化子は、それが定義されているクラスがクラス・ローダにロードされるとき、さらに詳しく言えば、そのクラスのインスタンスが最初に生成される際、コンストラクタが呼び出される前に実行されます。

static初期化子のデメリットは、例外を発生させることができないことらしい。例外が発生しない処理、あるいは例外が発生しても問題のない処理のみを記述しないと大変なことになる。

インスタンス初期化子

他にもJavaには、静的でない初期化子として、インスタンス初期化子(インスタンスイニシャライザ)も用意されている。インスタンス初期化子は、インスタンスの生成時に呼び出される。その構文は、以下のようになります。

{
  //初期化の処理
}

インスタンス初期化子で初期化する場合、初期化の対象となるフィールド値はインスタンス初期化子より先に書かれている必要がある。それさえ気をつければ書く位置に特に制約はない。

インスタンス初期化子が必要なときは無名内部クラス(無名インナークラス)の初期化のような特殊な状態に限られる。それ以外のときは通常通りコンストラクタに目的の処理をさせればよいのだろう。こういったテクニックは多用するとコードを見難くする危険性がある。

さてインナークラスというものを良く知らないので調べてみた。Java - インナークラスによるとインナークラスとはクラスの中にクラスを定義することのようだ。インナークラスはメンバと同じように扱えるそうだ。

class OuterClass{

    //インナークラス
    class InnerClass{

    }
}

インナークラスにアクセスするにはアウタークラスのインスタンスが必要だから、インスタンス初期化子を使って初期化しておくと処理が楽になるのかな?これについてはまた後で調べよう。Javaについては知らないことがたくさんだ。