자바는 Call by reference 가 없다

yookyungmin·2023년 4월 2일
0

자바에서는 call by reference가 없습니다. 오로지 call by value로 이루어 집니다.

Call by value는 인수로 전달된 값의 복사본이 함수나 메소드로 전달되는 방식입니다. 따라서 함수나 메소드에서 인수의 값을 변경해도 원래 변수의 값은 변경되지 않습니다.

참조 타입의 경우, 해당 변수는 메모리에서 객체를 가리키는 포인터입니다. 따라서 참조 타입 변수를 함수나 메소드의 인수로 전달할 때, 참조하는 객체의 값은 변경될 수 있습니다.


public void changeValue(int num) {
  num = 10;
}

int num = 5;
changeValue(num);
System.out.println(num); // 5

===============

public void changeValue(List<String> list) {
  list.add("Hello");
}

List<String> list = new ArrayList<>();
list.add("World");
changeValue(list);
System.out.println(list); // [World, Hello]

실제로 Call by reference가 아니며, Call by value이지만, 인수로 전달되는 값이 참조값(주소)이기 때문에 참조 타입 변수(객체)의 내부 상태를 변경할 수 있습니다. 이를 Call by reference처럼 보이게 할 수 있기 때문에 이러한 오해가 생길 수 있습니다.

포인터는 메모리 상의 주소를 가리키는 변수입니다. 메모리는 컴퓨터 시스템에서 프로그램이 사용하는 데이터를 저장하는 공간입니다.

자바 창시자 제임스 고슬링이 한 말씀입니다
"어떤 사람들은 잘못된 말로 객체가 '참조에 의해 전달(passed by reference)'된다고 말할 수 있다"는 내용을 전달합니다.
프로그래밍 언어 설계에서 '참조에 의한 전달(pass by reference)'이라는 용어는, 인자(argument)가 함수에 전달될 때, 호출된 함수가 원래 값의 참조(reference)를 가져온다는 것을 의미합니다. 이때, 값의 복사본이 아니라 원래 값의 참조를 가져온다는 것이 중요한데, 만약 함수가 인자(parameter)를 수정하면 호출 코드의 값도 변경됩니다. 이는 인자와 매개변수가 같은 메모리 슬롯을 사용하기 때문입니다.
하지만, 일부 사람들은 '참조에 의한 전달(pass by reference)'와 '값에 의한 전달(pass by value)'를 혼동하거나, 이용되는 용어가 문맥상 올바르지 않은 경우가 있습니다. 이를 통해 객체가 '참조에 의해 전달(passed by reference)'된다고 말하는 경우가 있는데, 이는 올바른 용어 사용이 아닙니다. 자바에서는 객체가 참조값으로 전달되므로, 이러한 혼동이 발생하기도 합니다.

토비의 스프링 저자 이일민님께서 하신 말씀입니다
원시(primitive) 타입과 참조(reference) 타입을 전달할 때 생기는 차이점을 설명하기 위해서 굳이 call by value, call by reference라는 어디서 많이 들어본 용어를 가져다 쓴 듯하다.
어쨌든, 나는 call by reference라는 용어를 가지고, 그걸로 레퍼런스(값)이라는 개념을 알고 있는지 확인하려는 기술면접 질문은 정말 아니다싶다.
혹시라도 그런 질문을 받는다면 의도를 파악하고, 적절하게 풀어서 답을 하긴 해야지. 자바에는 call by value 방식만 있는데, 레퍼런스 값을 call by value로 전달하면 호출된 메소드 내에서 호출 한 쪽에서 참조하고 있던 오브젝트 내부 값을 변경할 수 있다

0개의 댓글