Java에서의 Call by Value
public class Main {
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
System.out.println(a + " " + b);
}
public static void main(String[] args) {
int n = 10, m = 20;
swap(n, m);
System.out.println(n + " " + m);
}
}
// 결과
// 20 10
// 10 20Java는 함수에 인자를 넘길 때 값을 복사해서 전달한다. 이를 Call By Value라고 한다.
- 위 코드에서 swap(n,m)을 호출할 때 n,m 변수 자체가 함수에 전달되는 것이 아니라 10, 20이라는 값이 각각 새로운 지역 변수에 복사되어 전달된다.
- 함수 내부에서는 a,b의 값을 서로 바꿔 20 10이 출력되지만 함수 호출 이후 원래 n,m 값에는 변화가 없다.
그렇다면 함수 호출 이후 실제 n,m 값을 바꾸는 방법은 없을까?
결론적으로 primitive type 변수로는 불가능하다.
Java의 변수 전달 방식은 다음과 같다.
- int, char, double과 같은 primitive type 변수들은 값 자체가 복사되어 함수에 전달된다. 이 값들은 모두 Stack 영역에 저장된다.
- String, Integer, Array, 사용자 정의 클래스와 같은 referece type은 객체 자체는 Heap 영역에 저장되고 **Stack에 객체를 참조하는 주소값(Referece)**이 저장된다.
즉, 자바는 항상 Call By Value이며 Reference type을 전달할 때도 참조값의 복사본이 전달된다.
객체 내부의 값을 바꿀 수 있지만 참조 자체를 바꾸는 것은 불가능하다.
Reference Type을 이용한 Swap
class IntWrapper {
int value;
public IntWrapper(int value) {
this.value = value;
}
}
public class Main {
public static void swap(IntWrapper n, IntWrapper m) {
int temp = n.value;
n.value = m.value;
m.value = temp;
}
public static void main(String[] args) {
IntWrapper n = new IntWrapper(10);
IntWrapper m = new IntWrapper(20);
swap(n, m);
System.out.println(n.value + " " + m.value); // 20 10
}
}
요약
- Java는 항상 Call By Value이다.
- primitive type은 값 복사, reference type은 참조값 복사가 일어난다.
- primitive type으로는 swap 구현이 불가능하며 값을 변경하려면 객체를 감싼 reference type을 사용해야 한다.