この記事の要点
• コンストラクタはオブジェクト生成時に自動実行されるメソッド
• クラス名と同じ名前で、戻り値の型を書かない
• 複数の引数パターンを持つことができる(オーバーロード)
コンストラクタとは
コンストラクタ(Constructor) は、new でオブジェクトを作るときに自動的に呼ばれる特別なメソッドです。主な役割はフィールドの初期化です。
前回(第12回)で作った Person クラスを思い出してください。
// Java 21
public class Person {
String name;
int age;
}
この状態では new Person() でオブジェクトを作っても、name は null、age は 0 です。毎回セッターやフィールドアクセスで値をセットするのは手間なので、生成時に値を渡せる仕組みがコンストラクタです。
コンストラクタの定義方法
コンストラクタには以下の特徴があります。
| 特徴 | 説明 |
|---|---|
| クラス名と同じ名前 | Person クラスなら Person(...) と書く |
| 戻り値の型を書かない | void も書かない。何も書かない |
| 自動的に呼ばれる | new Person(...) のタイミングで実行される |
基本的なコンストラクタの例:
// Java 21
public class Person {
String name;
int age;
// コンストラクタ(引数なし)
public Person() {
name = "名無し";
age = 0;
}
}
これで new Person() と書くと、自動的に name に “名無し”、age に 0 がセットされます。
ポイント: コンストラクタは メソッドではあるが、普通のメソッドとは違う 特別なもの。戻り値を返さず、`new` 時だけ呼ばれます。
引数付きコンストラクタ
引数を受け取ることで、オブジェクト生成時に任意の値を設定できます。
// Java 21
public class Person {
String name;
int age;
// 引数付きコンストラクタ
public Person(String name, int age) {
this.name = name; // this.name = フィールド、引数の name と区別するため
this.age = age;
}
}
使い方:
// Java 21
Person alice = new Person("Alice", 25);
System.out.println(alice.name); // Alice
System.out.println(alice.age); // 25
補足: `this.name` の `this` は「自分自身のオブジェクト」を指します。引数名とフィールド名が同じ場合に必須です。
デフォルトコンストラクタの自動生成
クラスにコンストラクタを1つも定義しない場合、Java コンパイラが自動的にデフォルトコンストラクタ(引数なし、何もしない)を追加します。
| 状況 | 動作 |
|---|---|
| コンストラクタを書いていない | 自動的に public Person() {} が追加される |
| コンストラクタを1つでも書いた | 自動生成されない。引数なしで作りたい場合は明示的に定義する |
例:
// Java 21
public class Person {
String name;
int age;
// 引数付きコンストラクタだけを定義
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
// 使用例
Person p1 = new Person("Alice", 25); // OK
Person p2 = new Person(); // コンパイルエラー!
引数なしで作りたいなら、明示的に書く必要があります。
注意: 引数付きコンストラクタを1つでも定義すると、デフォルトコンストラクタは自動生成されません。両方使いたい場合は両方書いてください。
コンストラクタのオーバーロード
オーバーロード(Overload) は、同じ名前のメソッド(またはコンストラクタ)を、引数の型や個数を変えて複数定義する機能です。
| 引数パターン | 使い分け |
|---|---|
Person() | デフォルト値で初期化 |
Person(String name) | 名前だけ指定、年齢はデフォルト |
Person(String name, int age) | すべて指定 |
実装例:
// Java 21
public class Person {
String name;
int age;
// パターン1: 引数なし
public Person() {
this.name = "名無し";
this.age = 0;
}
// パターン2: 名前だけ
public Person(String name) {
this.name = name;
this.age = 0;
}
// パターン3: すべて指定
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
使い方:
// Java 21
Person p1 = new Person(); // 名無し, 0
Person p2 = new Person("Bob"); // Bob, 0
Person p3 = new Person("Charlie", 30); // Charlie, 30
ポイント: オーバーロードで「必須の引数だけ」「すべて指定」など柔軟な初期化パターンを提供できます。
this() でコンストラクタを再利用
コンストラクタから同じクラスの別のコンストラクタを呼び出すには this(...) を使います。重複コードを減らせます。
// Java 21
public class Person {
String name;
int age;
// 引数なし → 名前だけのコンストラクタを呼ぶ
public Person() {
this("名無し"); // Person(String) を呼ぶ
}
// 名前だけ → すべて指定のコンストラクタを呼ぶ
public Person(String name) {
this(name, 0); // Person(String, int) を呼ぶ
}
// すべて指定
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
補足: `this(...)` はコンストラクタの**最初の行**でしか呼べません。これは Java の仕様です。
コンストラクタとメソッドの違い
混同しやすいので整理します。
| 項目 | コンストラクタ | 普通のメソッド |
|---|---|---|
| 名前 | クラス名と同じ | 任意 |
| 戻り値の型 | 書かない(void も書かない) | 必須(void も含む) |
| 呼び出しタイミング | new 時に自動 | 明示的に呼ぶ |
| 役割 | オブジェクトの初期化 | 任意の処理 |
| オーバーロード | 可能 | 可能 |
実践例: 商品クラス
// Java 21
public class Product {
String name;
int price;
String category;
// すべて指定
public Product(String name, int price, String category) {
this.name = name;
this.price = price;
this.category = category;
}
// カテゴリは "その他" にする
public Product(String name, int price) {
this(name, price, "その他");
}
void display() {
System.out.printf("[%s] %s - %d円%n", category, name, price);
}
}
使用例:
// Java 21
public class Main {
public static void main(String[] args) {
Product p1 = new Product("ノートPC", 120000, "電子機器");
Product p2 = new Product("ボールペン", 150);
p1.display(); // [電子機器] ノートPC - 120000円
p2.display(); // [その他] ボールペン - 150円
}
}
ポイント: `this(...)` を使うことで、デフォルト値を持つコンストラクタを簡潔に書けます。
コンストラクタの使いどころ
| 場面 | 推奨パターン |
|---|---|
| 必須フィールドがある | 引数付きコンストラクタで必ず初期化する |
| オプションフィールドがある | オーバーロード + this() でデフォルト値を提供 |
| 不変(Immutable)なクラス | コンストラクタで全フィールドを確定し、セッターを作らない |
| 複雑な初期化ロジック | コンストラクタ内で検証や計算を行う |
注意: コンストラクタで例外を投げることも可能ですが、エラーハンドリングが複雑になるため慎重に。
まとめ
| 概念 | 説明 |
|---|---|
| コンストラクタ | new 時に自動実行される初期化メソッド |
| クラス名と同じ名前 | Person クラスなら Person(...) |
| 戻り値の型を書かない | void も不要 |
| デフォルトコンストラクタ | 何も書かないと自動生成されるが、1つでも書くと消える |
| オーバーロード | 引数パターンを複数持つことで柔軟な初期化を実現 |
this(...) | 同クラスの別コンストラクタを呼び出す |
次のステップ
Java入門 #14 - 標準入力(Scanner クラス) でユーザーからの入力を受け取る方法を学びます。
参考リソース
- Oracle Java Tutorial: Constructors — 公式チュートリアル
- Oracle Java SE 21 Specification — コンストラクタの仕様
- Effective Java (Joshua Bloch) — コンストラクタのベストプラクティス