1. キーワード new
Java では、任意のクラスのオブジェクトを作成するためにキーワード new を使用します。これは「魔法の」言葉で、JVM に「新しいオブジェクト用にメモリを確保し、そのコンストラクタを呼び出してほしい」と依頼します。
たとえ:
クラスが自動車の設計図だとすると、new はその設計図に基づいて実物の車を組み立てる工場です。
例
Person vasya = new Person();
ここで起きていること:
- new Person() — Person 型の新しいオブジェクトが作成されます(コンストラクタが呼び出される)。
- vasya — 作成されたオブジェクトへの参照を保持する変数です。
メモリ上ではどう見えるか
Person vasya = new Person(); と書くと、オブジェクトのフィールド(たとえば名前や年齢)のための領域がメモリに確保され、変数 vasya にはその領域のアドレス、つまり参照が格納されます。
注意:
new を書き忘れると、変数は何も指していない単なる参照(null)のままです。その「空の」オブジェクトのフィールドやメソッドにアクセスしようとすると、NullPointerException が発生します。
2. コンストラクタ呼び出しはどう動く?
コンストラクタは、オブジェクト生成時に呼び出され、そのフィールドを初期化してインスタンスを使用可能な状態にする特別なメソッドです。
構文
ImyaKlassa imyaPeremennoy = new ImyaKlassa(argumenty);
- クラスにパラメータ付きのコンストラクタがある場合は、必ずその引数を渡す必要があります。
- 引数なし(またはデフォルト)のコンストラクタなら、かっこは空のままです。
例: パラメータ付きコンストラクタ
public class Person {
String name;
int age;
// パラメータ付きコンストラクタ
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
オブジェクトを作成します:
Person petya = new Person("Petya", 25);
"Petya" と 25 の値が、新しいオブジェクトの name と age フィールドに格納されます。
引数なしコンストラクタ
public Person() {
this.name = "名無し";
this.age = 0;
}
これで次のように書けます:
Person mysteryMan = new Person(); // name="名無し", age=0
3. オブジェクトの操作: フィールドとメソッド
オブジェクトを作成したら、ドット演算子(.)を使ってそのフィールドやメソッドにアクセスできます:
petya.name = "Pyotr";
System.out.println(petya.name); // Pyotr
petya.sayHello();
クラスに次のようなメソッドがあるとします:
public void sayHello() {
System.out.println("こんにちは、私の名前は " + name + " です!");
}
すると、petya.sayHello(); の呼び出しは次を出力します: こんにちは、私の名前は Pyotr です!
例: 完成したクラス
public class Person {
String name;
int age;
public Person(String name, int age) { // コンストラクタ
this.name = name;
this.age = age;
}
public void sayHello() { // メソッド
System.out.println("こんにちは、私の名前は " + name + " です!");
}
}
使用例:
Person vasya = new Person("Vasya", 30);
vasya.sayHello(); // こんにちは、私の名前は Vasya です!
4. 参照型変数とは?
Java のクラス型の変数は、オブジェクトそのものではなく、メモリ上のオブジェクトへの参照です。
デモ
Person vasya = new Person("Vasya", 30);
Person anotherVasya = vasya;
これで vasya と anotherVasya は、メモリ上の同じオブジェクトを指します。片方の変数経由でフィールドを変更すると、もう一方から見ても変更されています:
anotherVasya.age = 31;
System.out.println(vasya.age); // 31
重要なポイント:
2 つの異なるオブジェクトを作成すれば、それらは独立です:
Person petya = new Person("Petya", 25);
Person masha = new Person("Masha", 22);
petya.age = 99;
System.out.println(masha.age); // 22 (変わらない!)
5. 例: 複数オブジェクトの生成と利用
アプリにいくつかオブジェクトを追加しましょう。クラス Person があり、main で複数の人を生成して挨拶を出力します。
Person クラス
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void sayHello() {
System.out.println("こんにちは、私の名前は " + name + " です。年齢は " + age + " 歳です!");
}
}
main での使用
public class Main {
public static void main(String[] args) {
Person vasya = new Person("Vasya", 25);
Person petya = new Person("Petya", 27);
vasya.sayHello(); // こんにちは、私の名前は Vasya です。年齢は 25 歳です!
petya.sayHello(); // こんにちは、私の名前は Petya です。年齢は 27 歳です!
// オブジェクトの独立性のデモ:
vasya.age = 100;
vasya.sayHello(); // こんにちは、私の名前は Vasya です。年齢は 100 歳です!
petya.sayHello(); // こんにちは、私の名前は Petya です。年齢は 27 歳です!
}
}
プログラムの出力:
こんにちは、私の名前は Vasya です。年齢は 25 歳です!
こんにちは、私の名前は Petya です。年齢は 27 歳です!
こんにちは、私の名前は Vasya です。年齢は 100 歳です!
こんにちは、私の名前は Petya です。年齢は 27 歳です!
6. オブジェクト生成でよくあるミス
エラー1: new の書き忘れ
Person vasya;
vasya.name = "Vasya"; // NullPointerException!
変数 vasya はどのオブジェクトも指していません(null)。必ず new でオブジェクトを作成しましょう。
エラー2: コンストラクタへパラメータを渡していない
Person petya = new Person(); // デフォルトコンストラクタがない場合はコンパイルエラー
クラスにパラメータ付きコンストラクタしかない場合、オブジェクト生成時にそのパラメータを必ず指定する必要があります。
エラー3: 変数がオブジェクトそのものを保持していると考えてしまう
Person a = new Person("Anya", 20);
Person b = a;
b.age = 99;
System.out.println(a.age); // 99。a と b は同じオブジェクトへの参照だからです!
Java では、クラス型の変数は常に参照であり、オブジェクト本体ではありません。
エラー4: 一方のオブジェクトのフィールドを変更しても、もう一方は変わらないと思っている
Person x = new Person("X", 1);
Person y = x;
x.age = 42;
System.out.println(y.age); // 42
独立した 2 つのオブジェクトが必要なら、別々に生成してください!
GO TO FULL VERSION