스터디/Java 스터디

[Java] Call by value vs Call by reference

제이온 (Jayon) 2022. 4. 11.

java-study에서 스터디를 진행하고 있습니다.

 

Call by value

  • 메소드를 호출할 때 넘겨 주고 싶은 인자를 지정하면, 메소드의 매개 변수가 지정한 변수 값의 복사본으로 초기화되는 것이다.
  • 따라서 함수 내에서의 변경은 메소드를 호출할 때 지정한 변수(원본)에 아무 영향을 미치지 않는다.

 

Call by reference

  • 메소드를 호출할 때 넘겨 주고 싶은 인자를 지정하면, 메소드의 매개 변수가 지정한 변수의 레퍼런스로 초기화되는 것이다.
  • 따라서 함수 내에서의 변경은 메소드를 호출할 때 지정한 변수(원본)에 영향을 미친다.

 

Java는 Call by value? Call by reference?

Java에서 객체를 전달 받고, 그 객체를 수정하면 원본도 같이 수정되므로 Call by reference처럼 보인다. 그러나 Java는 Call by value이다. 예시를 살펴 보자.

 

 

여기서 주의 깊게 봐야 하는 부분은 a1의 value가 111로 변경된 것이다. arg1의 value를 변경하니 원본 a1의 값이 변경되었기 때문에 이것을 Call by reference라고 생각할 수 있다.

그러나 a1에서 arg1으로 인자를 넘기는 과정에서 직접적인 참조를 넘긴 것이 아닌, 주소 값을 복사해서 넘기기 때문에 이것은 Call by value이다. 복사된 주소 값으로 참조가 가능하니 주소 값이 가리키는 객체의 내용이 변경되는 것이다.

 

좀 더 자세히 알아보기 위해 JVM의 메모리 영역을 살펴 보자.

 

1. run() 메소드 실행 전

 

2. run() 메소드 실행 후

 

  • arg1은 a1이 가지고 있는 주소 값을 복사하여 독자적으로 갖는다.
  • arg2도 마찬가지로 a2가 가지고 있는 주소 값을 복사하여 독자적으로 갖는다.
  • 주소 값을 복사하여 가져 가는 Call by value가 발생한다.

 

3. run() 메소드의 첫 번째 줄 실행

 

 

  • arg1을 통해 value의 값을 변경한다면, arg1이 가지고 있는 주소 값을 통해 객체의 값을 변경한다.

 

4. run() 메소드의 두 번째 줄 실행

 

  • arg2가 arg1이 가진 주소 값을 복사하여 저장한다.
  • a2와 arg2는 독립된 변수이기 때문에 a2는 변경되지 않는다.

 

C++에서 Call by reference

C++에서는 포인터를 통해 메모리 주소를 개발자가 직접 다룰 수 있다. 즉 매개 변수를 변경할 경우 원본도 같이 변경되는 Call by reference를 구현할 수 있다.

 

#include<iostream>
using namespace std;

class A {
public:
    int value;
    A(int value) {
        this->value = value;
    }
};

void run(A* arg1, A* arg2) {
    arg1->value = 111;
    *arg2 = *arg1;
};

int main() {
    A* a1 = &A(1);
    A* a2 = &A(2);
    run(a1, a2);
    cout << "a1 : " << a1->value << ", a2 : " << a2->value;
    system("pause");
    return 0;
}

 

a1과 a2가 각각 arg1, arg2로 참조를 넘기므로 a1과 a2의 값이 모두 111로 변경되는 것을 확인할 수 있다.

 

 

출처

 

예상 면접 질문 및 답변

Call by value와 Call by reference의 차이

Call by value는 메소드를 호출할 때 넘겨주고 싶은 변수(인자)를 지정하면, 메소드의 매개변수가 지정한 변수 값의 복사본으로 초기화되는 것이다.

Call by reference는 메소드를 호출할 때 넘겨주고 싶은 변수(인자)를 지정하면, 메소드의 매개변수가 지정한 변수의 레퍼런스로 초기화되는 것이다.

 

Java는 Call by value일까, Call by reference일까?

Java에서 인자를 넘기는 과정에 직접적인 참조를 넘긴 게 아닌, 주소 값을 복사해서 넘기기 때문에 이는 Call by value이다.

'스터디 > Java 스터디' 카테고리의 다른 글

[Java] Reflection 개념 및 사용 방법  (0) 2022.04.03
[Java] 원시 타입 vs 참조 타입  (0) 2022.03.26
[Java] hashCode() vs equals()  (1) 2022.03.02
[Java] static이란?  (3) 2022.03.01
[Java] Java 8 vs Java 11  (2) 2022.02.10

댓글

추천 글