Call by Value, Call by Reference

Yellta·2024년 9월 7일
0

Call by Value(값에 의한 호출)

  • 값을 복사하여 처리한다.
  • 변수의 복사본이 전달되며, 원래 값이 수정되지 않는다.
  • 실제 인수는 다른 메모리 위치에 생성된다.

Call by Reference(참조에 의한 호출)

  • 값의 주소를 참조하여 직접 값에 영향을 준다.
  • 변수 자체가 전달되며, 원래 값이 수정된다.
  • 실제 인수는 같은 메모리 위치에 생성된다.

자바의 Call by Value 동작 방식

원시 타입 (Primitive type)

  • Numeric Type(byte, short, int, float, long, double, char), Boolean

참조타입(reference type)

  • Class Type, Interface, Array, Enum, 기타등등(String포함)
public class CallByExampleTest {  
    @Test  
    void primitiveTest(){  
        int v = 10;  
  
        add(v);  
  
        assertThat(v).isEqualTo(10);  
    }  
    void add(int num){  
        num++;  
    }  
}

자바에서 변수를 선언하면 Stack메모리 영역에 할당한다.

Stack 영역안에서 PrimitiveTest메소드와 add 메소드의 영역이 따로 나뉘어져있고 변수도 각가 존재한다.
따라서 원시타입의 전달은 값을 복사해서 전달하는 Call by Value 방식으로 동작한다.

참조 타입 (reference type)전달 방식

변수는 stack에 있지만 객체는 Heap 영역에 위치한다.
Stack에 있는 변수가 Heap영역에 있는 객체를 바라보고 있는 것이다.

@Test  
void referenceTest() {  
    int[] arr = {10};  
    add2(arr);  
  
}  
void add2(int[] arr){  
    arr[0]++;  
}

여기서 add2의 메소드는 referenceTest에서 선언된 배열을 사용하고 있다.
어찌보면 결국 add가 일어나고 주소값이 바뀌니 Call By Value라고 생각할 수도 있지만
자바에서 참조의 의미는 객체가 힘에 저장된 위치를 가르키는 메모리 주소이다.

Call by Reference는 참조 자체를 넘기기때문에 새로운 객체를 할당하면 원본 변수도 영향을 받는다.

그러면 전달받은 값을 새로운 객체로 변경하면 어떻게 될까?

    @Test

    void referenceTest() {

        int[] arr = { 10 }; // 0x001
        newArr(arr);
        assertThat(arr).isEqualTo("0x001");

    }
    void newArr(int[] arrArg) {
        arrArg = new int[]{ 20 }; // 0x002
    }

전달 받은 값을 새로운 객체로 변경해도 원본의 변수는 변하지 않는다.

![[Pasted image 20240908020734.png]]

자바는 언제나 Call by Value형태로 데이터를 전달하고, 호출자 변수와 수신자 파라미터는 Stack 영역 내에서 각각 독립적으로 존재하는 다른 변수이다.


참고

https://dev-coco.tistory.com/189

https://bcp0109.tistory.com/360

profile
Yellta가 BE개발해요! 왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜왜 가 제일 중요하죠

0개의 댓글