Java は、オブジェクトとプリミティブ型の両方で値渡しを使用します。Java は参照の値を渡すため、ターゲットの値は変更できますが、アドレスは変更できません。
これは C++ と比べてどうですか?
違いは、呼び出し元の関数で変数に影響を与えることができるかどうかです。
オブジェクトはしばらく脇に置きましょう。純粋に値渡しである Java では、呼び出された関数に渡された変数の呼び出し関数の値を変更することはできません。例:
void foo() {
int a = 42;
bar(a);
System.out.println("foo says: " + a);
}
void bar(int a) {
a = 67;
System.out.println("bar says: " + a);
}
を呼び出すとfoo
、次のように表示されます。
バーのコメント: 67 フー 言います: 42
bar
を変更できませんでしfoo
たa
。
値渡しの場合、C++ でこれが当てはまります。ただし、参照渡しの場合は、呼び出し元のコードの変数への参照を渡しています。そして、それは呼び出されたコードがそれを変更できることを意味します:
void foo() {
int a = 42;
bar(a);
cout << "foo says: " << a;
}
void bar(int& a) {
a = 67;
cout << "bar says: " << a;
}
は参照( )bar
を受け取ると定義されていることに注意してください。を呼び出すと、次のように表示されます。int& a
bar
バーのコメント: 67 フー 言います: 67
bar
内の値を変更できました。a
foo
では、オブジェクト参照を扱いましょう: まず、「参照」という言葉が 2 つのまったく異なるものに使用されていることに注意してください:呼び出し関数内の変数への参照(参照渡しのもの) とオブジェクトへの参照。オブジェクト参照を Java のメソッドに渡す場合、他のすべてと同様に、参照は値によって渡されます。
void foo() {
List list = new ArrayList();
List ref2 = list; // (Let's remember that object reference for later...)
bar(list);
System.out.println("foo says: " + list.size());
System.out.println("foo says: Same list? " + (ref2 == list));
}
void bar(List list) {
// `bar` can modify the state of the object the reference points to
list.add(new Object());
System.out.println("bar says (after add): " + list.size());
// ...but cannot change `foo`'s copy of `list`
list = new ArrayList();
System.out.println("bar says (after new): " + list.size());
}
ご覧のように:
バーは言う(追加後):1 バーは言う(新しい後):0 フー 言います: 1 foo は言う: 同じリスト? 真実
bar
は参照が (値によって) 渡されたオブジェクトの状態を変更できますがfoo
、そのオブジェクトへの の参照は変更できません。foo
作成された新しいリストが表示されませんbar
。
Java では、プリミティブと参照を値で渡すことができます。他のオプションはありません。
C++ では、値または参照によってプリミティブとポインターを渡すことができます。参照渡しの場合、メソッドに渡された後に値またはポインターに加えられた変更が表示され、元の値を変更できます。
違いは、呼び出し元の関数で変数に影響を与えることができるかどうかです。
オブジェクトはしばらく脇に置きましょう。純粋に値渡しである Java では、呼び出された関数に渡された変数の呼び出し関数の値を変更することはできません。例:
void foo() {
int a = 42;
bar(a);
System.out.println("foo says: " + a);
}
void bar(int a) {
a = 67;
System.out.println("bar says: " + a);
}
foo を呼び出すと、次のように表示されます。
bar の発言: 67 foo の発言: 42 bar は foo の a を変更できませんでした。
値渡しの場合、C++ でこれが当てはまります。ただし、参照渡しの場合は、呼び出し元のコードの変数への参照を渡しています。そして、それは呼び出されたコードがそれを変更できることを意味します:
C++ では、Java に相当するものはこれです
void Swap(Type* A, Type* B)
{
// here we have pointers to type A (in Java they are called references and don't use * syntax)
A->DoThis() // can call with -> a method on object
//if you try to swap A with B not possible because we don't have A*/B* reference
// see bellow how to do this
}
C++ で上からの制限を処理する方法は次のとおりです。
void Swap(Type& A, Type& B)
{
Type& temp = A;
A = B;
B = temp;
}