Java의 call by value

tony·2023년 11월 4일
post-thumbnail
  1. 자바는 기본적으로 메소드 호출 시 Call by value 이다.
  2. 기본형(primitive) 변수는 실제 값이 전달된다.
  3. 참조형(reference) 변수는 실제 저장된 값인 "주소값"이 전달된다.
  4. 참조형 변수에는 class instance, 배열 등이 있다.

아래 코드는 nums의 주소값이 전달되고 해당 주소의 실제 값이 업데이트 되는 것을 확인할 수 있다

public static void main(String[] args) {
  int[] nums = {1,2,3};
  changeFirst(nums);
}

public static void changeFirst(int[] input) {
  input[0] = 3;
}


changeFirst 함수가 호출되면서 스택에 쌓이고 input 매개변수가 메인함수의 nums의 값이 전달되었다. 그러므로 nums와 input이 갖고 있는 값(주소)이 같아지므로 서로 바라보고 있는 값이 동일하다. 그러므로 input[0]의 값을 변경했을 때 nums의 실제 값도 변경되는 것을 확인 할 수 있다.

아래 코드는 비교를 위해 작성한 코드로 결과를 예상해보자.

@AllArgsConstructor
class A {
  private int value;
}

public static void main(String[] args) {
  A a1 = new A(1);
  A a2 = new A(2);
  copyInstance(a1, a2);
  //<-- 과연 copy가 이뤄졌을까
}

public static void copyInstance(A arg1, A arg2) {
  arg1 = arg2;
}

copyInstance 메소드를 통해 주소값이 복사되므로 객체 복사가 잘 이루어졌을까? 스택 영역과 힙 영역의 그림을 보면서 확인해보자.

위 그림은 함수가 호출하고 arg2의 값이 arg1으로 할당된 시점을 보여준다. 이후 함수 종료 후 스택에서 copyInstance는 없어질 것이다. 그러면 아래 그림과 같다. 카피가 잘 이뤄졌는지 확인해보자.

매개변수가 가리키는 값만 변경되었다가 스택에서 사라진 모습이고, 결국 아무런 영향도 없는 코드임을 확인 할 수 있다. 객체 복사에 관한 내용은 다른 주제이므로 생략하도록 하겠다.

정리

  • Java는 call by value로 함수 호출한다.
  • 기본형의 value는 "실제값", 참조형의 value는 "주소값"이다.
  • 참조형 매개변수는 주소값이 전달되지만 함수 호출이 끝난 후 스택에서 사라지는 값이다.
profile
백엔드 서버 엔지니어

0개의 댓글