이번에는 함수를 호출 할 때 파라미터를 넘기는 방법으로 Call by Value와 Call by Reference에 대해서 정리를 해보았다.
Java언어에서는 Primitive 타입을 전달할 때는 원본에 영향을 끼치지 않고 Reference 타입을 전달할 때는 원본에 영향을 끼치므로 Call by Value와 Call by Reference를 적절히 사용하는 언어인가 생각을 할 수 있다. 나 또한 오히려 Call by Reference에 가깝지 않은가 생각을 해왔지만 이번에 학습을 하면서 제대로 배움을 얻게 되었다.
public void Main(){
int a = 10;
int b = 5;
Test(a, b);
//a는 10, b는 5
System.out.println("a는 " + a + ", " + "b는 " + b);
}
public void Test(int a, int b){
a = 20;
b = 10;
}
간단한 예제로 설명을 하자면 Main에서 Primitive 타입의 변수가 Stack 영역에 할당되고 각 각 10, 5 값을 가지게 된다. 그리고 Test 함수를 호출하면서 Primitive 타입의 변수가 새로 Stack 영역에 할당되고 값이 각 각 20, 10을 가지게 되는 것이다.
public void Main(){
Person a = new Person(5);
Person b = new Person(10);
Test(a, b);
//a의 나이는 6, b의 나이는 11
System.out.println("a의 나이는 " + a.age + ", " + "b의 나이는 " + b.age);
}
public void Test(Person a, Person b){
a.age++;
b.age++;
}
public void Person{
int age;
public Person(int age){
this.age = age;
}
}
이번에는 Primitive 타입이 아닌 Reference 타입일 때를 예시로 설명해 보았다. 위에 예제를 실행을 하게 된다면 Test 함수의 호출로 인해 원본데이터가 변하게 되어 a의 나이는 6, b의 나이는 11가 출력이 되며, Call by Reference가 아닌가? 라는 생각을 가질 수 있다.
public void Main(){
Person a = new Person(5);
Person b = new Person(10);
Test(a, b);
//a의 나이는 5, b의 나이는 10
System.out.println("a의 나이는 " + a.age + ", " + "b의 나이는 " + b.age);
}
public void Test(Person a, Person b){
a = new Person(10);
b = new Person(20);
}
public void Person{
int age;
public Person(int age){
this.age = age;
}
}
만약 Call by Reference 라면 위에 예시도 a의 나이는 10, b의 나이는 20이 출력이 되어야 하지만 실제로는 a의 나이는 5, b의 나이는 10이 출력이 된다.
Java(Reference Type)의 2가지 예시를 설명해 보겠다.
실제로 Reference Type을 인수로 넘길때는 참조를 넘기는 것이 아니라 주소값의 복사값이 인수로 넘어가며 Stack 영역에 같은 주소값을 가리키는 변수가 2개가 되는 것이다.
참고 문서 및 링크