[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends:00668] Re: Java の初期化



> 初期化を行うメソッドがstaticメソッドとすればよいかと。
初期値をメ
> ソッドから得るのはよいスタイルと思います。
> class Test {
>   int a = getDefaultA();
>   static int getDefaultA() {
>     return 111;
>   }
> }
初期化の順番の問題ですね。
int a がstaticになったらまた同じ問題になってしまい
そうな気がします。
> > クラスが初期化されていないのだからメソッドが
> > 正しく動かないはずなのに、正常動作してします。
> > 複雑な場合はちょっとちがいますが・・
> > どのように説明すればいいのでしょうか?
> staticメソッドでない場合も、必ずしも正しくないとは言え
ないと思い
> ます。正しく動作するには多分以下の2点が条件として必要
になります。
> ・メソッドの中で同じクラスのフィールドを参照する場合、
先に初期化
> されていることを設計上保証すること
この1つめの条件は必然ですね
そうしないとObjectならNull、プリミティブならそれ相当
の初期化しか行われないので正しくないですから。
> ・メソッドがサブクラスでオーバーライドされることを想定
して設計す
> るか、オーバーライドを禁止すること
> これが満たされていないならば、いろいろな状況下で「正常
に動作して
> いる」のではなく、ある状況下で「たまたま動作している」
だけではな
> いでしょうか?
そうです、たまたまかもしれませんが
class Oya {
	int i = getInt();
	public int getInt(){
		return 1;
	}
}
class Ko extends Oya{
	public int getInt(){
		return 2;
	}
	public static void main(String[] args){
		System.out.println(new Ko().i);
	}
}
という例で結果は2になります。
初めの質問は
「インスタンス変数の初期化をメソッドで設定するのは
おかしいと思うのですが、なにがおかしいか説明
できない」ということなのです。
1つ目の条件は正しいと思います。でも、初めの例では、メソ
ッド内で変数は使用していません。
オーバーライドを考えて設計しても、子クラスを作る人が
バグを埋め込むのは止めようがないので親クラスの責任では
ない気がします。
javapしてみたら
メソッドで初期化
Method Oya()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 aload_0
   5 aload_0
   6 invokevirtual #2 <Method int getInt()>
   9 putfield #3 <Field int i>
  12 return
}
そのまま初期化
Method Oya()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 aload_0
   5 iconst_1
   6 putfield #2 <Field int i>
   9 return
}
でした。
どうでしょうか?

__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!
http://bb.yahoo.co.jp/


------------------------------------------------------------------------
      ★あなたのホームページに“最新ニュース”をお届け!!      
         http://ap.infoseek.co.jp/ticker2.html