プロが教えるわが家の防犯対策術!

JAVAやJavascript、最近オブジェクト指向的な記述が可能になったphpなどの言語で次のようなクラス定義が可能です。

<JAVAの場合>
class A {
public int i1 = 1;
public int i2;
A() {
i2 = 2;
}
}

しかし最近覚えたC++では、例の「public int i1 = 1;」のようなクラスのスコープ内で代入を行うことは出来ず、その場所では「public int i2;」のように宣言のみ、代入はコンストラクタで行うようになっています。この場合はなぜ「public int i1 = 1;」はダメなのかと疑問に思っても「そういう仕様だ」と言われれば納得できます(やり方が1つだけなので)。

ではJAVAなどの言語で、例のような場所で「public int i1 = 1;」のような宣言と代入を行うことは、代入をコンストラクタを用いて行うこととどのような違いがあるのでしょうか?また、どちらが推奨されるのでしょうか?

A 回答 (4件)

No2さんの内容をちょっと補足。


フィールドの初期化は、スーパークラスのコンストラクタより後、自分自身のコンストラクタの処理より先です。
コンストラクタの起動後ですが、コンストラクタの初期化処理より先に動きます。

コンストラクタで行っているフィールドへの代入を当てにして初期化を書くと変なことになります。
    • good
    • 0

No.2の回答の方が言うとおり、違いはわずかでどちらにすべきという強い理由はないと思います。

ただ、自分はコンストラクタが大きくなるのを嫌って可能な限りフィールドの宣言と同時に初期化するのが好きです。これはローカル変数の宣言と初期化を1ステートメントで行う理由と同じです。もちろんフィールドの初期化にコンストラクタの引数が必要な場合はコンストラクタで初期化せざるをえません。
    • good
    • 0

記述上の制限という言葉で片付けてしまうのもやや乱暴ですが


varable initializeによるインスタンス変数の初期化はConstractor
の起動より先に実行されることはありません。
記述上「宣言」と「代入」を同時に行っているようにみえますが違います。
実際にはコンパイラがConstractor内にvarable initializeを内部展開し
Constractorが*起動した後で*その初期化が実行されます。
なので結局はConstractor内に初期化コードを記述することと差異はないのです。

実際にjavap -cでJavaを実行してみるとその順序が明確ですので
確認してみるとよいかもしれません。

JLS文書の「8.3.2 Initialization of Fields」も参照のこと。

結局のところコード標準や周囲のソースコードとの比較を元に
もっとも「らしい」記述を心がけるのがよいでしょう。
この手の課題に今のところ「べき論」はありません。
    • good
    • 0

どーなんでしょうねえ。


基本的に、static や final 以外は コンストラクタで代入するのがスジだと思います。
final変数は書き換えできないので、宣言時に指定するしかありませんし、
static変数はインスタンス化の影響を受けないので、宣言時に指定するのが妥当だと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!