コンストラクタのコードトレース

コンストラクタはnewで作る実体の初期状態を設定します。クラス名と同じ名前で戻り値型を書かない宣言、暗黙のデフォルトコンストラクタ、引数による選択、thisによる連鎖を学びます。

この単元で学ぶこと

  • コンストラクタと通常メソッドを区別する
  • デフォルトコンストラクタの有無を判定する
  • 引数と初期化順から生成後の状態を求める

本文解説

thisで共通初期化へ委譲 Box(){this(4);}Box(int n){this.n=n;}なら引数なし生成も4で初期化します。this(4)は新しい別実体を作るのではなく、同じ生成中の実体に対する別コンストラクタへ処理を任せます。

委譲後の追加処理 Box(){this(4);n++;}なら委譲先でn=4となった後に5へ増えます。実行順は呼出し先を完了してから元の本体の残りです。初期化子はthis連鎖のコンストラクタ数だけ繰り返すわけではありません。

先頭文の制約 Java 11ではthis(...)をコンストラクタ本体の先頭へ置く必要があります。n=2;this(4);は不正です。通常メソッド内でthis(4)を呼ぶこともできません。thisという参照式とthis(...)という特別な呼出し構文を区別します。

再帰的な連鎖は不正 Box(){this(1);}Box(int n){this();}は互いに呼び合うためコンパイルエラーです。実行してStackOverflowErrorになる前に、コンストラクタ呼出しの循環が検出されます。最後に初期化を完了する経路が必要です。

型によるオーバーロード Box(int n)とBox(long n)があれば整数リテラル3はint版、3Lはlong版です。byte変数はintへ拡大してint版を選べます。intをshortへ暗黙縮小してコンストラクタを選ぶことはできません。

戻り値のない終了 コンストラクタでreturn;を使って早く終了することはできますがreturn 1;は不正です。コンストラクタには戻り値型がなく、new式の参照は通常メソッドのreturn値として作るものではありません。finalフィールドの代入保証も守る必要があります。

アクセス制限 private Box()なら別トップレベルクラスからnew Box()はできません。Box内部のstaticな生成メソッドでnew Box()を行い、その参照を公開する設計は可能です。privateで生成経路を管理しても、許可された場所での生成そのものを禁止するわけではありません。

例外で完了しない生成 コンストラクタ内で例外が送出されればnew式は正常に値を返しません。呼出し元の後続表示は実行されず、その場で未処理例外が伝わります。フィールド初期化やコンストラクタの記述が合法でも、生成が必ず成功するとは限りません。

図解

生成時の初期化の順
継承時の親初期化の詳細は継承単元で扱う。

重要ポイント

  • コンストラクタ名はクラス名と同じで戻り値型を書かない。
  • 一つも宣言しない場合にだけデフォルトコンストラクタが与えられる。
  • 引数の数や型が違うコンストラクタをオーバーロードできる。
  • Java 11のthis(...)はコンストラクタ本体の先頭文に置く。

間違えやすい点

  • voidを付けた同名メソッドをコンストラクタと思わない。
  • 引数付きだけ宣言してもnew C()が使えると考えない。
  • コンストラクタを通常のメソッド呼出しで再実行しようとしない。

用語解説

コンストラクタ
実体生成時に初期状態を設定する特別な宣言。
デフォルトコンストラクタ
明示宣言がないクラスにコンパイラが与えるコンストラクタ。
コンストラクタ連鎖
this(...)やsuper(...)で別のコンストラクタへ処理を委譲すること。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。