« コーディング規約とコーディングパターンは違う | トップページ | nullと空集合は違う »

2007年1月21日 (日)

インスタンス化の無限ループについて

●インスタンス化の無限ループについて

クラスのフィールドで、非staticなフィールドに、そのクラス自身のインスタンスの生成を記述すると、そのクラスのインスタンス化時にインスタンス生成の無限ループが発生して、スタックオーバーフローで落ちる。
ただし、staticなフィールドに自己のクラスを生成している場合は落ちない。

クラスのインスタンス化時に、そのクラスのフィールドは初期化されるのだが、そこでそのクラス自身のインスタンス化が行われている場合、無限ループが発生するのである。
それゆえにスタックオーバーフローで落ちてしまう。
これは中身が空のクラスでも起こる。

一方、非staticなフィールドで自己のクラスを生成している場合、staticなフィールドはプログラム内で1つしか存在しないことが保障されているため、無限ループは発生しない。

ネット上で同様の問題が論じられているページはないか探してみたが、以下のサイトを発見した。
1 - 6 : クラス生成時エラー

構文の意味的には、無限ループが発生するのが素直な解釈なのであるが、staticの場合は無限ループにはならないようである。

問題は、このような自己生成フィールドを持つクラスの使用法・用途だろう。
staticな自己生成フィールドはシングルトンのデザインパターンで利用可能である。
(この場合はコンストラクタをprivateにする必要がある)
そして、非staticな自己生成フィールドはスタックオーバーフローで落ちるのだが、このフィールドにも何らかの利用法があるのだろうか? 謎である。

また今回新たに分かったのは、staticな自己生成フィールドで生成されたオブジェクトと、同じクラスのオブジェクトが他のクラス内で生成された場合、それら2つは異なるオブジェクトであるということだった。言葉にするとわかりずらいのでソースを見て欲しい。

以下はサンプルソース

/**
*  インスタンスの無限生成によるスタックオーバーフロー現象
*/
public class C7 {

public static void main(String[] args) {
 
  // ここで、C7_1クラスのstaticフィールドが初期化される
  // 初期化されたC7_1オブジェクトの m メソッドを呼び出す
  C7_1.c7_1s.m();
 
  // このような記述方法も可能。ただし、C7_1 オブジェクトは唯一な存在。
  C7_1.c7_1s.c7_1s.c7_1s.c7_1s.c7_1s.c7_1s.c7_1s.c7_1s.c7_1s.m();

  // ここで作成されるオブジェクトは、
  // C7_1クラス内のc7_1sが指すオブジェクトと違うものである
  C7_1 c7_1 = new C7_1();

  // C7_1.c7_1s と c7_1 の参照するオブジェクトは同じか? --> 違う
  if(C7_1.c7_1s == c7_1){
   System.out.println("同じオブジェクト");
  } else {
   System.out.println("違うオブジェクト");
  }

  // C7_1.c7_1s と c7_1.c7_1s の参照するオブジェクトは同じか? --> 同じ
  if(C7_1.c7_1s == c7_1.c7_1s){
   System.out.println("同じオブジェクト");
  } else {
   System.out.println("違うオブジェクト");
  }
 
}

}

class C7_1{

// クラスアクセス時にstatic変数は初期化される
// これがnewされるのは一回のみ。(つまり c7_1s は唯一のオブジェクトにある)
static C7_1 c7_1s = new C7_1();

// こいつがあると無限にnewが走ってスタックオーバーフローになる
//C7_1 c7_1 = new C7_1();

void m(){
  System.out.println("test");
}


}

出力結果:

test
test
違うオブジェクト
同じオブジェクト

|

« コーディング規約とコーディングパターンは違う | トップページ | nullと空集合は違う »

コメント

>ネット上で同様の問題が論じられているページはないか探してみたが、以下のサイトを発見した。
>1 - 6 : クラス生成時エラー

リンク先サイトが再構築されたのかもしれません。
ここでしょうか。
//amsoft.minidns.net/node/8

投稿: a | 2011年6月22日 (水) 11時39分

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック


この記事へのトラックバック一覧です: インスタンス化の無限ループについて:

« コーディング規約とコーディングパターンは違う | トップページ | nullと空集合は違う »