[JAVA] Call by value 와 Call by reference

in·2023년 8월 30일
0

JAVA

목록 보기
2/9

call by value

값에 의한 호출

  • 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시공간이 생성됨
    ➡️ 종료 시 해당 공간 사라짐

  • 함수 호출 시 전달되는 변수 값을 복사해서 함수 인자로 전달
    ➡️ 이때 복사된 인자는 함수 안에서 지역적으로 사용되기 때문에 local value의 속성 가짐

     void func(int n) {
         n = 20;
     }
    
     void main() {
         int n = 10;
         func(n);
         printf("%d", n);
     }

call by reference

참조에 의한 호출

  • 호출 방식은 함수 호출 시 인자로 전달되는 변수의 레퍼런스 전달
  • 함수 안에서 인자 값이 변경되면 argument로 전달된 객체의 값도 변경됨
  void func(int *n) {
      *n = 20;
  }

  void main() {
      int n = 10;
      func(&n);
      printf("%d", n);
  }

Java 함수 호출 방식

항상 call by value로 값을 넘김
C/C++와 같이 변수의 주소값 자체를 가져올 방법이 없으며 이를 넘길 수 있는 방법 또한 없음
참조 자료형(reference type)을 넘길 때는 해당 객체의 주소값을 복사하여 사용


User a = new User("gyoogle");   // 1

foo(a);

public void foo(User b){        // 2
   b = new User("jongnan");    // 3
}

/*
==========================================

// 1 : a에 User 객체 생성 및 할당(새로 생성된 객체의 주소값을 가지고 있음)

a   -----> User Object [name = "gyoogle"]

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

// 2 : b라는 파라미터에 a가 가진 주소값을 복사하여 가짐

a   -----> User Object [name = "gyoogle"]
              ↑     
b   -----------

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

// 3 : 새로운 객체를 생성하고 새로 생성된 주소값을 b가 가지며 a는 그대로 원본 객체를 가리킴

a   -----> User Object [name = "gyoogle"]
                  
b   -----> User Object [name = "jongnan"]

*/

파라미터 객체/값의 주소값을 복사하여 넘겨주는 방식을 사용하고 있는 Java는 주소값을 넘겨 주소값에 저장되어 있는 값을 사용하는 call by reference라고 오해할 수 있음

C/C++와 Java 비교

C/C++

// c/c++ 

int a = 10;
int b = a;

cout << &a << ", " << &b << endl; // out: 0x7ffeefbff49c, 0x7ffeefbff498

a = 11;

cout << &a << endl; // out: 0x7ffeefbff49c

C/C++에서는 생성한 변수마다 새로운 메모리 공간을 할당하고 이에 값을 덮어씌우는 형식으로 값을 할당
(* 포인터를 사용한다면 같은 주소값을 가리킬 수 있도록 함)

Java
//java
 
 int a = 10;
 int b = a;
 
 System.out.println(System.identityHashCode(a));    // out: 1627674070
 System.out.println(System.identityHashCode(b));    // out: 1627674070
 
 a = 11;

 System.out.println(System.identityHashCode(a));    // out: 1360875712

Java에서 또한 생성한 변수마다 새로운 메모리 공간을 갖는 것은 마찬가지이지만 그 메모리 공간에 값 자체를 저장하는 것이 아니라 값을 다른 메모리 공간에 할당하고 이 주소값을 저장하는 것

➡️ C/C++에서는 주소값 자체를 인자로 넘겼을 떄 값을 변경하면 새로운 값으로 덮어 쓰여 기존 값이 변경되고, Java에서는 주소값이 덮어 쓰여지므로 원본 값은 전혀 영향이 가지 않음

정리

Call by value의 경우 데이터 값을 복사해서 함수로 전달하기 때문에 원본의 데이터가 변경될 가능성이 없다. 하지만 인자를 넘겨줄 때마다 메모리 공간을 할당해야해서 메모리 공간을 더 차지한다.

Call by reference의 경우, 메모리 공간 할당 문제는 해결했지만 원본 값이 변경될 수 있다는 위험이 존재한다.

[참고 자료]

🔗링크1

0개의 댓글