본문 바로가기
Java/기초

[Java] Java는 Call by reference가 없다

by EricJeong 2020. 3. 24.

Call by Value와 Call By Reference가 뭘까?

프로그래밍을 하다 보면 꼭 알고 넘어가야 하는 개념이 있습니다. 바로 Call By Value, Reference입니다. 어떤 언어를 공부하든 나오는 개념이기도 합니다. 

 

Call by value란, 값을 호출하는 것을 의미합니다. 전달받은 값을 복사하여 처리합니다. 즉 전달받은 값을 변경하여도 원본은 변경되지 않습니다.

 

Call by reference란 참조에 의한 호출을 의미합니다. 전달받은 값을 직접 참조합니다. 즉 전달받은 값을 변경할 경우 원본도 같이 변경이 됩니다.

 

 

Java에 Call by reference가 있을까?

우리는 Java에서 객체를 전달받고, 그 객체를 수정하면 원본도 같이 수정되니 이것이 Call by reference라고 생각합니다.

 

예를 들기 위해 클래스 A를 만들어보겠습니다. 클래스 A는 public 접근 지정자인 변수 value를 가지고 있고 이를 생성자의 매개변수로 받습니다.

 

A의 상태를 변경하는 메서드 run도 만들어보겠습니다. A 클래스 형태로 매개변수 arg1, arg2를 받습니다. arg1의 value를 111로 변경하고 arg2arg1을 저장합니다.

 

 

 

여기서 주의깊게 봐야 하는 부분은 a1의 value가 111로 변경된 것입니다. arg1의 value를 변경하니 원본 a1의 값도 변경되었으니 이 것을 call by reference라고 헷갈리는 것이죠. 하지만 a1에서 arg1으로 매개변수를 넘기는 과정에서 직접적인 참조를 넘긴 게 아닌, 주소 값을 복사해서 넘기기 때문에 이는 call by value입니다. 복사된 주소 값으로 참조가 가능하니 주소 값이 가리키는 객체의 내용 변경되는 것입니다.

 

조금 더 하위 레벨에서, JVM 메모리 레벨로 코드가 진행될 때 어떻게 되는지 확인해보겠습니다. main에서 a1, a2를 만든 부분까지 진행했을 때 JVM 메모리는 아래와 같은 형태입니다.

 

뺄거 다 빼고 필요한것만 표시한 JVM 메모리

 

그리고 run 메서드가 실행되며 매개변수를 전달받으면 다음과 같은 상황이 됩니다. arg1은 a1이 가지고 있는 주소값을 복사하여 독자적으로 가지게 됩니다. arg2도 마찬가지로 a2가 가지고 있는 주소 값을 복사하여 독자적으로 가지고 있게 됩니다. 주소 값을 복사하여 가져 가는 call by value가 발생한 것이죠.

 

 

 

여기서 arg1을 통해 value의 값을 변경한다면 arg1이 가지고 있는 주소 값을 통해 객체의 값을 변경하게 됩니다.

 

 

 

arg2에 arg1의 값을 저장한다고 해도 이는 run 메서드 내에 존재하는 arg2가 arg1이 가진 주소값을 복사하여 저장하는 것일 뿐 원본 a2와는 독립된 변수이기 때문에 원본 a2는 변경되지 않습니다.

 

 

 

 

즉 Java는 기본적으로 모든 전달 방식이 Call by value입니다.

 

댓글