コンストラクタの罠
このレッスンでは、デフォルトコンストラクタが消える条件と this() の使い方を判定できるようになります。
まず予測してください
次のコードはコンパイルできるでしょうか。
class Box {
int size;
Box(int size) {
this.size = size;
}
}
Box b = new Box(); // ここは通る?答えはコンパイルエラーです。Box() という引数なしのコンストラクタが存在しないからです。
デフォルトコンストラクタは「1つも書かなかったとき」だけ生まれる
Java のコンパイラは、クラスにコンストラクタが1つも書かれていないときに限って、引数なしのコンストラクタを自動で足します。これがデフォルトコンストラクタです。
つまり Box(int size) を1つでも自分で書いた瞬間、自動生成は行われません。引数なしで作りたければ、自分で Box() を書き足す必要があります。試験ではこの一点だけを突いてくる問題が繰り返し出ます。
this() は先頭にしか置けない
同じクラスの別のコンストラクタを呼ぶときは this(...) を使います。ここにも決まりがあります。
class Box {
int size;
Box() {
this(10); // 必ず1行目
}
Box(int size) {
this.size = size;
}
}覚えることは次の3つです。
this(...)はコンストラクタの先頭行でなければならない。2行目に書くとコンパイルエラーthis(...)とsuper(...)は同じコンストラクタに同時に書けない。どちらも先頭を要求するためthis(...)で自分自身を呼ぶと再帰的な呼び出しとみなされ、コンパイルエラーになる
コンストラクタは戻り値の型を書かない
もう1つの定番の引っ掛けが、戻り値の型を付けてしまう形です。
class Box {
void Box() { } // これはコンストラクタではなく、ただのメソッド
}void が付いた時点でこれは Box という名前のメソッドです。コンストラクタは1つも書かれていないと判断されるので、デフォルトコンストラクタが生成され new Box() は通ります。読み飛ばすと必ず間違えるので、選択肢に void が混ざっていないかを毎回確かめてください。
演習で確かめます
引数なしで作ったときの既定値と、引数ありで作ったときの値の両方を返して、this() の連鎖が実際に効いていることを目で確かめます。
要件
- Box に引数なしのコンストラクタを追加し、その中で this(10) を呼ぶこと
- Box(int size) は書き換えないこと
- build は new Box() と new Box(n) の 2 つを作り、size をカンマ区切りでつないだ文字列を返すこと
入出力例
build(3) → "10,3"
build(7) → "10,7"
build(0) → "10,0"ヒント
編集 LuaGate編集部