CallByValue와 CallByReference는 메서드에서 인자 값을 받을 때 어떠 한식으로 값을 받아 올 것 인가에 대한 방식이다.
두 방식은 값에 의한 호출인가 혹은 참조에 의한 호출 인가로 구별할 수 있다.
CallByValue
메서드 호출 시점에 사용하는 인자에 저장되어있는 값을 복사하여 보낸다.
예제를 들어서 설명해보자!
/**
* Project : EffectiveStudy
*
* @author : jwdeveloper
* @comment :
* Time : 4:31 오후
*/
public class CallByValue {
public static void swap(int n1, int n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
public static void main(String[] args) {
int n1 = 2;
int n2 = 5;
swap(n1,n2);
System.out.println(n1);
System.out.println(n2);
}
}
위의 코드의 실행 결과는 아래와 같이 값이 바뀌지 않았다.
값만 복사해서 넘겼기 때문에 main 함수에서 사용되는 변수에는 영향을 주지 않는다.
조금 더 구체적으로 말하자면 swap() 함수를 호출하는 시점에는 temp 변수와 n1, n2 가 새롭게 스택에 쌓이게 된다.
(기존의 n1, n2는 Scope이 다르기 때문에 완전히 다른 존재 이다.)
} 괄호를 만나는 순간 해당 함수에서 생겨난 stack의 변수들은 POP이 되며 다시 기존 Stack에 쌓였던 n1,n2로 돌아오게된다.
(이때 n1, n2에는 값의 변화가 없음을 볼 수 있다.)
Call By Reference
- call-by-reference 참조에 의한 호출방식은 함수 호출 시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가리킨다.)
- 따라서 함수 안에서 인자의 값이 변경되면, 아규먼트로 전달된 객체의 값도 함께 변경된다.
예시 (C 언어)
#include <iostream>
using namespace std;
void sum(int* a, int* b){
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int a1 = 10;
int a2 = 20;
sum(&a1, &a2);
cout << "a1: " << a1 << " a2: " << a2 << endl;
return 0;
}
변수의 래퍼런스를 전달받아서 해당 래퍼런스가 참조하고 있는 메모리의 변수 값을 바꾸어 준다.
반면 JAVA에서는 Call By Reference가 존재할까?
결론부터 말하자면 존재하지 않는다.😅
예시 (JAVA)
/**
* Project : EffectiveStudy
*
* @author : jwdeveloper
* @comment :
* Time : 4:49 오후
*/
public class CallByReference2{
public static void swap(Person person0, Person person1) {
String temp = person0.getName();
person0.setName(person1.getName());
person1.setName(temp);
}
public static void main(String[] args) {
Person person0 = new Person("junwoo", 30);
Person person1 = new Person("jwdeveloper", 30);
swap(person0, person1);
}
}
결과가 바뀌긴 바뀌었다!
그렇다면 자바도 Call By Reference 가 존재한다고 생각해도 되는구나!
가 아니다.
왜냐면 Call By Reference는 주소를 가리키는 래퍼런스 아규먼트로 전달하는 게 아닌 실제 주소를 전달해야 한다.
위의 C 예시에서는 포인터를 사용해 실제 메모리 주소를 직접적으로 참조하고 있으니 C언어에는 Call By Reference가 존재하는 것이 분명하지만 자바에서는 실제 메모리 주소를 직접적으로 참조할 수 있는 포인터와 같은 개념이 없기 때문에 존재하지 않는다고 말할 수 있다.
References
https://yaboong.github.io/java/2018/05/26/java-memory-management/
https://multifrontgarden.tistory.com/87
https://blog.naver.com/gngh0101/221160889447
http://wonwoo.ml/index.php/post/1679
https://yaboong.github.io/java/2018/05/26/java-memory-management/
'Java > Java' 카테고리의 다른 글
(JAVA) HashMap은 테이블 인덱스를 어떻게 구하는가? (1) | 2021.01.31 |
---|---|
(JAVA) HashSet은 정렬을 지원하지 않는다고 들었는대? (2) | 2021.01.27 |
(JAVA) Garbage Collector (0) | 2020.05.10 |
(JAVA) Method 오버라이딩에 대해서 (0) | 2020.04.15 |
(JAVA) Method Overloading에 대해서 (0) | 2020.04.07 |