본문 바로가기

old/Programming

Java 메소드 매개변수 참조 변경 불가: 왜 그럴까요?

반응형

질문

Java에서는 메소드 매개변수로 전달된 참조를 변경하여 원본 객체를 수정하는 것이 불가능합니다. 왜 그럴까요?

개요

Java에서는 메소드 매개변수로 전달된 배열의 참조를 변경하여 원본 배열을 수정하는 것이 불가능합니다.

이유

Java는 메소드 호출 시 매개변수를 값에 의한 복사(call by value)로 전달합니다. 배열은 참조 타입이므로, 메소드 내부에서 배열 매개변수에 새로운 배열을 할당하면 해당 매개변수는 새로운 배열을 가리키게 됩니다. 그러나 이 변경은 메소드 외부에 있는 원본 배열에는 영향을 주지 않습니다.

이는 자바가 call by value language라 불리는 이유입니다.

사용 방법

Java에서는 배열을 직접 수정하는 것이 아니라 복사하여 변경한 후, 변경된 배열을 새로운 변수에 할당하는 방법을 사용해야 합니다. 즉, 필드 값을 개별적으로 수정해야 합니다.

장점

  • 메소드 호출 시 원본 배열이 변경되지 않아 예기치 않은 부작용이 발생할 확률을 줄입니다.
  • 코드의 가독성과 유지보수성이 향상됩니다.

단점

  • 복사한 배열을 새로운 변수에 할당해야 하므로, 메모리 사용량이 늘어날 수 있습니다.
  • 배열의 크기가 매우 큰 경우에는 성능에 영향을 줄 수 있습니다.

예제

import java.util.*;

public class ArrayExample {
    public static void main(String[] args) {
        int[] originalArray = {1, 2, 3, 4, 5};
        int[] copiedArray = modifyArray(originalArray);

        System.out.println("Original Array: " + Arrays.toString(originalArray));
//        Original Array: [1, 2, 3, 4, 5]
        System.out.println("Copied Array: " + Arrays.toString(copiedArray));
//        Copied Array: [2, 4, 6, 8, 10]
    }

    public static int[] modifyArray(int[] array) {

        // 원본 배열 변경을 시도하지만, 원본 배열에는 영향을 주지 않습니다.
        array = Arrays.stream(array)
                .map(num -> num * 2)
                .toArray();

        // 배열 요소를 변경하기 위해 새로운 배열을 생성합니다.
        int[] newArray = Arrays.copyOf(array, array.length);
        for (int i = 0; i < newArray.length; i++) {
            newArray[i] *= 2;
        }

        return newArray;
    }
}

위의 코드에서 Arrays.stream(array).map(num -> num * 2).toArray()는 기존의 int 배열을 스트림으로 변환해서 수정을 시도합니다. 하지만, 원본 배열에는 영향을 주지 않습니다.

newArray는 배열을 복사하여 새로운 배열을 생성한 후, 해당 배열의 요소를 변경하여 반환합니다. 이를 통해 원본 배열 originalArray는 변경되지 않고, copiedArray에는 변경된 배열이 할당됩니다. copyOf() 메서드를 사용하여 배열을 복사했습니다. 이 메서드는 새로운 배열을 생성하여 원본 배열의 요소를 복사합니다. 그런 다음 newArray의 요소를 변경하더라도 originalArray에는 영향을 주지 않습니다.

반응형