Call은 Retrofit에서 많이 봤는데..
아무튼 이 둘은 비슷하면서 비슷하지 않은 개념인데 메모리 구조를 아신다면 이해가 빠르실겁니다.
우리가 구현하는 함수들이 호출 될때는 메모리 공간 안에서 임시의 공간이 생성됩니다.
함수가 종료되면 해당 공간은 사라지게 되고요
이때 함수 호출시 변수를 어떤 방식으로 전달하느냐에 따라 Call by value 와 Call by reference 로 나뉩니다.
- 기본 자료형 : Call by value 로 동작 (int, String, short, long, float, double, char, boolean)
- 참조 자료형 : Call by reference 로 동작 (Array, Class의 Instance)
- 장점: 복사하여 처리하기 때문에 안전하다. 원래의 값이 보존
- 단점: 복사를 하기 때문에 메모리가 사용량이 늘어남
예제
public class ValueTest {
public static void changeValue(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println("a: "+ a +" b:" + b);
changeValue(a, b);
System.out.println("a: "+ a +" b:" + b);
}
}
>> a: 1 b: 2
>> a: 1 b: 2
출력한 값을 확인하면 바뀌지 않았다.
이런식으로 Call by value는 값을 복사하여 인자로 넘기기 때문에 a와 b의 값을 changeValue()
함수안에서만 바뀌기 때문에 값을 바꾸더라도 실제 a와 b의 값는 바뀌지 않습니다.
- 장점 : 복사하지 않고 직접 참조를 하기 때문에 빠름
- 단점 : 직접 참조를 하기 때문에 원래 값이 영향을 받음
예제
public class ReferenceTest {
int value;
public ReferenceTest(int value) {
this.value = value;
}
public static void changeValue(ReferenceTest x, ReferenceTest y) {
int tmp = x.value;
x.value = y.value;
y.value = tmp;
}
public static void main(String[] args) {
ReferenceTest a = new ReferenceTest(1);
ReferenceTest b = new ReferenceTest(2);
System.out.println("a: "+ a.value +" b:" + b.value);
changeValue(a, b);
System.out.println("a: "+ a.value +" b:" + b.value);
}
}
위의 코드에서 보면 ReferenceTest라는 객체를 만들어서 참조 변수인 x와 y를 넘기므로 Call by reference입니다.
☝ 그러나 이때 changeValue(a, b);
에서 a와 b의 객체 주소값을 직접 넘기는 게 아닌 a객체와 b객체를 가르키는 또다른 주소값을 넘깁니다.
평소에 알고 있던 개념이지만 막상 설명해 보라고 하면 헷갈리는 것이라 정리하며 개념을 다시 익힌 것 같다!!👍
메모리 공부는 더 하는걸로..