Javaの引数は値渡しなのか、参照渡しなのか
正直知ってても知らなくても困ることはないのですが、Javaの引数の渡し方のお話です。
Javaは参照渡しと言われることが多くて、でもなんだかそのあたり腹落ちせずもやもやしてたのがC++の勉強をしていて霧が晴れた感があったので記事にしてみました。
くり返しになりますが、別にJavaに限っていったら知っててても知らなくてもどうでもいいことです。
プリミティブ型の場合
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println("Before swap");
System.out.println("a = " + a);
System.out.println("b = " + b);
swap(a, b);
System.out.println("After swap");
System.out.println("a = " + a);
System.out.println("b = " + b);
}
static void swap(int x, int y) {
System.out.println("In swap");
int t = x;
x = y;
y = t;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
出力
Before swap
a = 1
b = 2
In swap
x = 2
y = 1
After swap
a = 1
b = 2
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println("Before swap");
System.out.println("a = " + a);
System.out.println("b = " + b);
swap(a, b);
System.out.println("After swap");
System.out.println("a = " + a);
System.out.println("b = " + b);
}
static void swap(int x, int y) {
System.out.println("In swap");
int t = x;
x = y;
y = t;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Before swap
a = 1
b = 2
In swap
x = 2
y = 1
After swap
a = 1
b = 2
swap
メソッドの引数x
、y
は呼び出し元のa
、b
のコピーであり異なる実体です。したがって、swap
メソッドの中でx
とy
の値が入れ替わっても呼び出し元に影響は及びません。
これがすなわち値の値渡し
です。
オブジェクトの場合
public static void main(String[] args) {
Integer c = new Integer(1);
Integer d = new Integer(2);
System.out.println("Before swap");
System.out.println("c = " + c);
System.out.println("d = " + d);
swap(c, d);
System.out.println("After swap");
System.out.println("c = " + c);
System.out.println("d = " + d);
}
static void swap(Integer x, Integer y) {
System.out.println("In swap");
Integer t = x;
x = y;
y = t;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
出力
Before swap
c = 1
d = 2
In swap
x = 2
y = 1
After swap
c = 1
d = 2
public static void main(String[] args) {
Integer c = new Integer(1);
Integer d = new Integer(2);
System.out.println("Before swap");
System.out.println("c = " + c);
System.out.println("d = " + d);
swap(c, d);
System.out.println("After swap");
System.out.println("c = " + c);
System.out.println("d = " + d);
}
static void swap(Integer x, Integer y) {
System.out.println("In swap");
Integer t = x;
x = y;
y = t;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Before swap
c = 1
d = 2
In swap
x = 2
y = 1
After swap
c = 1
d = 2
結果はプリミティブ型と同じく、swap
メソッド内で値が入れ替わっても、呼び出し元の値は入れ替わりません。
swap
メソッドにはIntegerクラスのインスタンスに対する参照が引数として渡されます。
ただし、引数に渡される参照は、プリミティブ型の場合と同じく呼び出し元における参照のコピーとなります。
つまり、swap
メソッドでx
とy
の参照を入れ替えたとしても呼び出し元a
とb
の参照は変更されません。
これはすなわち参照の値渡し
ということなります。
でも、オブジェクトの場合参照を引数に渡してるんだから参照渡しっていってもいいんじゃない?
以降は余談です。
厳密な意味での参照渡しって、たぶんC++でいうところの参照を引数として受け渡しすることだと思うんです。
でも、私が大昔すこしだけC言語をかじったときも引数の値渡し、参照渡しっていい方をしていた記憶があって、C言語の参照渡しってポインタを引数として渡すことだと思うですが、これも厳密にいうとポインタの値渡し
です。
正直なところ、C言語での文脈とか理解が曖昧なのですが、もしポインタの値渡し
を参照渡しという文脈があるなら、Javaのオブジェクトだって、参照渡しといってもいいんじゃない?
自分なりの結論
厳密にはJavaは値渡しである。
でも、暴論めいたことを言うと、参照渡しと言ってそれも間違ってはないっしょ。
本当に大切なのは
それが値渡しだろうが参照渡しだろうが、Javaに関してはオブジェクト引数にわたす場合その参照が渡されることには違いない。
参照の向き先はメソッドの呼び出し元、メソッド内でもおなじになるので、メソッド内で参照介してオブジェクトを操作した場合、呼び出し元に副作用的に影響が及び得る、ということです。
Author And Source
この問題について(Javaの引数は値渡しなのか、参照渡しなのか), 我々は、より多くの情報をここで見つけました https://qiita.com/yachinco/items/9f95cd08cb8975a30979著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .