[Java] 자바는 Call by Reference가 없다고?

𝒄𝒉𝒂𝒏𝒎𝒊𝒏·2023년 4월 14일
0

Java

목록 보기
3/4
post-thumbnail

✔️ 파라미터 전달 방식

메소드의 파라미터 전달 방식에는 Call by ValueCall by Reference 두 가지 방식이 있다.

▶︎ Call by Value(Pass by Value)

Call by value는 메소드의 파라미터로 변수의 값을 복사해서 전달하는 방식이다.
즉, 원래의 값에 영향을 주지 않고 함수 내로 복사된 값을 전달하며, 값을 복사하기 때문에 변수의 크기가 클수록 비용이 증가하게 된다.

▶︎ Call by Reference(Pass by Reference)

Call by Reference는 메소드의 파라미터로 변수의 주소를 전달하는 방식이다.
즉, 변수의 주소를 전달하기 때문에 원래 변수의 값에도 영향을 줄 수 있다.


✔️ Java의 파라미터 전달 방식

아래 예제 코드 2개를 통해 Java의 파라미터 전달 방식을 살펴보겠다.

▶︎ Call by Reference 같은데..

예제 코드 1)

public class CallByReferenceExample {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println("Before calling modifyArray method: " 
        					+ Arrays.toString(arr));
        modifyArray(arr);
        System.out.println("After calling modifyArray method: "
        					+ Arrays.toString(arr));
    }
    
    public static void modifyArray(int[] arr) {
        arr[0] = 0;
        arr[1] = 0;
        arr[2] = 0;
    }
}

위 코드에서는 세 개의 요소로 배열을 만들고, modifyArray 메소드에 전달 후, modifyArray 메소드 내부에서 배열의 요소를 0으로 수정한다. 메소드 호출 전후에 배열 내용을 인쇄하면 메소드 내부에서 수정한 내용도 원래 배열에 영향을 미쳤음을 알 수 있다.

실행 결과 : 
Before calling modifyArray method: [1, 2, 3]
After calling modifyArray method: [0, 0, 0]

modifyArray 메소드는 main 메소드 arr 배열과 같은 메모리에 접근한다.
여기까지만 보면 마치 Call by Reference인 것 처럼 보인다.
이제 다음 예제 코드를 보겠다.


▶︎ 참조를 변경 해보자

예제코드 2)

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    modifyStringBuilder(sb);
    System.out.println(sb.toString()); // prints "Hello, world!"
}

public static void modifyStringBuilder(StringBuilder sb) {
    sb.append(", world!");
    sb = null; // main()의 변수에 영향을 주지 않는다.
}

이 코드에서는 StringBuilder 객체를 modifyStringBuilder 메서드에 전달한다.
메서드 내에서 StringBuilder 객체에 ", world!"를 추가하여 객체를 수정한다.
그 후 sb 매개 변수를 null로 설정하며 참조 변경을 시도한다.
그러나 실제로는 main 메소드sb에는 영향을 주지 않는 것을 알 수 있다.


✔️ 결론

자바에서는 개발자가 직접 메모리 주소에 접근 할 수 없다.
파라미터의 전달은 원시값이 복사 되느냐 주소값이 복사되느냐의 차이가 있으며,

원시값인 경우 바로 연산을 수행하고, 주소값인 경우 해당 메모리 주소를 참조하여 값을 가져와
연산을 수행하거나 저장할 수 있다. 그러나 참조 대신 다른 객체를 할당하여도 원본을 변경 할 수 없다.

즉, 변수가 가르키는 객체의 주소를 전달 받았을 뿐, 변수가 다른 값(객체)을 가르키도록 변경 할 수는 없다.

profile
𝑶𝒏𝒆 𝒅𝒂𝒚 𝒐𝒓 𝒅𝒂𝒚 𝒐𝒏𝒆.

0개의 댓글