- ベストアンサー
インスタンスフィールドの初期化方法
クラスのインスタンスフィールドを初期化する場合、次の3つが考えられますが、どれが一番スマートなんでしょうか。 クラスQ1はインスタンス変数int xを持つとします。 1.コンストラクタ内で初期化 e.g. Q1() {this.x = 1;} 2.宣言時に初期化 e.g. int x = 1; 3.インスタンス初期化子内で初期化 e.g. { x = 1; } Q1(){}
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
スマート、という表現が主観的なので正解はなさそうに思います。強いて言えば、一つのプログラム内で意味もなく複数のやり方を混ぜて使うのはスマートじゃないだろうな、というくらいです。 参考までに、私は基本的にコンストラクタ内で初期化しています。staticな定数なら宣言時に初期化。インスタンス初期化子は使ったことがありませんし、人のプログラムでも見たことがありません。
その他の回答 (2)
- hrm_mmm
- ベストアンサー率63% (292/459)
私は、趣味プログラマなので、「こうやってる」というだけですが、 3番は、初期化子の前に、宣言は必須です。よって3番は冗長なだけであり、2番の方がわかりやすくバグの危険が減ると思います。 あと、初期化データのためによほど複雑な計算があるなら、初期化子内でやることもあるのかもしれないけど、初期値にそんな複雑なデータを持たせる必要はいままでなかったので、初期化子自体使ったことがありません。 1番は、コンストラクタでの初期化時に、引数などから初期化用データをとりたいときに使います。 定数代入なら、2番にすることが多いです。eclipseを使ってると、変数の宣言部分参照で、どんなデータが入ってるかもすぐわかるので。
お礼
>>3番は、初期化子の前に、宣言は必須です。 例ですので、当然先頭に宣言があります。すみませんでした。 >>2番の方がわかりやすくバグの危険が減ると思います。 この点は私も賛同です。 >>初期化データのためによほど複雑な計算があるなら、 >>初期化子内でやることもあるのかもしれない そうですね。 乱数値を代入したり、日付を取得するなどの作業は初期化子内で記述した方がスッキリするかも。 つまり、全コンストラクタ共通の処理を初期化子として独立させるには使えるかも知れませんね。 >>初期化子自体使ったことがありません。 これが多数はなのでしょうか。 >>eclipseを使ってると、変数の宣言部分参照で、 >>どんなデータが入ってるかもすぐわかるので。 この機能は知りませんでした。
- komi1341
- ベストアンサー率65% (25/38)
いろいろな方の意見を聞けるといいですね。 追加の質問の件のみ回答させて頂きます。 > 宣言時に初期化かつコンストラクタでも同じ値で初期化するのは、意味のないことでしょうか。 逆にお聞きするようですが、そうすることに意味またはメリットはありますか? 私には保守性の面でのデメリットしか見えてきません。 例えばあるとき、別の値で初期化したくなったらどうするのでしょう。宣言部とコンストラクタ内と、両方修正するのでしょうか。単純に考えて面倒です。動作上はコンストラクタの方のみ値を変えれば想定通りになるでしょうが、宣言部と違う値で初期化されているのを他人が見たら、理解に苦しむでしょう。1年も放置すれば、自分のプログラムも他人が書いたものみたいに感じるものなので、未来の自分を困惑させることになるかもしれません。 そういうデメリットを上回るぐらいのメリットがないなら、いずれか一つの方法で初期化した方がよいと思います。
お礼
>>私には保守性の面でのデメリットしか見えてきません。 そうですね。浅はかでした。 他の方がどの方法で初期化してるのか参考にしてみたいですね。
お礼
>>スマート、という表現が主観的なので正解はなさそうに思います。 そうですね。みんなの意見を聞いてみたいです。 >>一つのプログラム内で意味もなく >>複数のやり方を混ぜて使うのは >>スマートじゃないだろうな 確かに。 >>私は基本的にコンストラクタ内で初期化しています 私はいつも宣言時に初期化していました。 宣言時に初期化かつコンストラクタでも同じ値で初期化するのは、意味のないことでしょうか。