함수를 호출할 때 인자의 값을 어떻게 넘길지 결정하는 방식인데
Call by Value는 값 자체를 복사하여 넘기고
Call by Reference는 참조를 넘긴다.
우선 아래의 예제 코드를 살펴보자
public class CallTest {
public static void main(String[] args) {
LoginEntity entity = new LoginEntity("test1", "123");
System.out.println(entity.toString());
// output userId = test1, pw = 123
foo(entity);
System.out.println(entity.toString());
// output userId = test1, pw = 12345
}
private static void foo(LoginEntity entity) {
entity.setPw("12345");
}
}
foo
메소드에서 pw
파라미터를 "12345"로 바꿨더니
원본도 바뀐 것을 확인할 수 있다.
보통은 이를 보고 Call by Reference라고 생각한다.
필자도 그랬다
하지만 사실 Java는 Call by Value로 작동하는데
Java는 인자를 넘길 때 주소값을 복사해서 넘긴다.
그렇기 때문에 메소드 내에서 이 주소값을 가지고 원본에 접근이 가능하고
파라미터의 값도 변경이 가능하기 때문에
마치 Call by Reference처럼 보인다.
그렇다면 주소값은 어떻게 넘기는걸까?
Java는 변수를 할당할 때 값 그대로 대입하는 것이 아닌
값을 임의의 메모리 공간에 넣어두고 해당 메모리 주소를
변수에 할당한다.
이를테면
int a = 10;
a라는 변수에 10을 할당한다면
Java는 10을 '100'이라는 주소를 가진 메모리에 넣어두고
a에는 10이 있는 메모리의 주소값인 '100'을 할당한다.
그렇다면 값의 변경은 어떻게 이루어질까?
기존의 '100'이라는 주소를 가진 메모리 안에 있는 값 10을 변경하는 것이 아닌
새로운 '101'이라는 주소를 가진 메모리에 새로운 값을 넣고
변수 a에 새로운 값이 있는 메모리의 주소값 '101'을 할당한다.
즉, 값이 변경되면 새로운 메모리에 값을 넣어 할당한다.
int a = 10;
System.out.println(System.identityHashCode(a)); // output 705927765
a = 11;
System.out.println(System.identityHashCode(a)); // output 366712642
개인적으로 공부했던 것을 바탕으로 작성하다보니
잘못된 정보가 있을수도 있습니다.
인지하게 되면 추후 수정하겠습니다.
피드백은 언제나 환영합니다.
읽어주셔서 감사합니다.