Java Language
オブジェクト参照
サーチ…
備考
これは "Null Pointer Exception"を理解するのに役立つはずです。オブジェクト参照がnullなので、そのうちの1つを取得しますが、プログラムコードはそのオブジェクト参照で何かを使用することを期待しています。しかし、それは独自のトピックに値する...
メソッドパラメータとしてのオブジェクト参照
このトピックでは、 オブジェクト参照の概念について説明します 。 Javaでプログラミングを初めて経験した人を対象にしています。クラス定義、メインメソッド、オブジェクトインスタンス、オブジェクトの "on"メソッドの呼び出し、メソッドへのパラメータの渡しなど、いくつかの用語と意味に慣れているはずです。
public class Person {
private String name;
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public static void main(String [] arguments) {
Person person = new Person();
person.setName("Bob");
int i = 5;
setPersonName(person, i);
System.out.println(person.getName() + " " + i);
}
private static void setPersonName(Person person, int num) {
person.setName("Linda");
num = 99;
}
}
Javaプログラミングを十分に理解するためには、この例をあなたの頭の上の誰かに説明することができます。その概念は、Javaの仕組みを理解する上で基本的なものです。
ご覧のように、変数person
オブジェクトをインスタンス化するmain
があり、そのオブジェクトのname
フィールドを"Bob"
に設定するメソッドを呼び出します。次に、別のメソッドを呼び出し、 person
を2つのパラメータの1つとして渡します。もう1つのパラメータは5に設定された整数変数です。
呼び出されたメソッドは、渡されたオブジェクトのname
値を "Linda"に設定し、渡された整数変数を99に設定してから戻ります。
では、何が印刷されるのですか?
Linda 5
だから、なぜperson
なされた変更がmain
に反映されるのですか?整数に加えられた変更はなぜですか?
呼び出しが行われると、mainメソッドはperson
オブジェクト参照をsetPersonName
メソッドにsetPersonName
ます。 setAnotherName
がそのオブジェクトに対して行う変更はそのオブジェクトの一部であり、メソッドが戻るときにそれらの変更はそのオブジェクトの一部です。
同じことを言うもう一つの方法: person
はオブジェクト(ヒープに保存されている場合は、興味があれば)を指します。メソッドがそのオブジェクトに対して行う変更は、そのオブジェクトに対して行われ、変更を行うメソッドがまだアクティブであるか返されたかによって影響を受けません。メソッドが復帰すると、オブジェクトに加えられた変更はすべてそのオブジェクトに保存されます。
渡された整数とこれを比較してください。これはプリミティブ int(Integerオブジェクトインスタンスではない)なので、渡された "値によって"、その値はメソッドに渡され、渡された元の整数へのポインタではありません。メソッドは、しかし、それはメソッド呼び出しが行われたときに使用される変数には影響しません。
Javaでは、すべてのプリミティブが値渡しされます。オブジェクトは参照渡しされます。つまり、オブジェクトへのポインタが、それらを受け取るメソッドにパラメータとして渡されます。
明らかではないことは、呼び出されたメソッドが新しいオブジェクトを作成し、それをパラメータの1つとして返すことは不可能であることを意味します。メソッドがメソッド呼び出しによって直接的または間接的に作成されたオブジェクトを返す唯一の方法は、メソッドの戻り値としてです。最初にそれがどうやってうまくいかないのか、どうしたらうまくいくのかを見てみましょう。
私たちの小さな例にもう一つの方法を追加しましょう:
private static void getAnotherObjectNot(Person person) {
person = new Person();
person.setName("George");
}
main
に戻り、 setAnotherName
の呼び出しの下で、このメソッドともう1つのprintln呼び出しを呼び出しましょう:
getAnotherObjectNot(person);
System.out.println(person.getName());
今度はプログラムが出力します:
Linda 5
Linda
ジョージを持っていたオブジェクトには何が起こったのですか?さて、渡されたパラメータはLindaへのポインタでした。 getAnotherObjectNot
メソッドが新しいオブジェクトを作成したとき、それはLindaオブジェクトへの参照をGeorgeオブジェクトへの参照に置き換えました。 Lindaオブジェクトはまだ(ヒープ上に)存在していますが、 main
メソッドはまだそれにアクセスできますが、 getAnotherObjectNot
メソッドはそれへの参照がないため、その後は何もできません。コードの作者は、新しいオブジェクトを作成して戻す方法を意図していたようですが、そうであれば機能しませんでした。
それが作者がやりたいことであれば、メソッドから新しく作成されたオブジェクトを返す必要があります。
private static Person getAnotherObject() {
Person person = new Person();
person.setName("Mary");
return person;
}
それからこれを次のように呼んでください:
Person mary;
mary = getAnotherObject();
System.out.println(mary.getName());
プログラム全体の出力は次のようになります。
Linda 5
Linda
Mary
両方の追加があるプログラム全体がここにあります:
public class Person {
private String name;
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public static void main(String [] arguments) {
Person person = new Person();
person.setName("Bob");
int i = 5;
setPersonName(person, i);
System.out.println(person.getName() + " " + i);
getAnotherObjectNot(person);
System.out.println(person.getName());
Person person;
person = getAnotherObject();
System.out.println(person.getName());
}
private static void setPersonName(Person person, int num) {
person.setName("Linda");
num = 99;
}
private static void getAnotherObjectNot(Person person) {
person = new Person();
person.setMyName("George");
}
private static person getAnotherObject() {
Person person = new Person();
person.setMyName("Mary");
return person;
}
}