HOWTO · Java
Java에서 값으로 전달된 배열 또는 참조로 전달된 배열
이 기사에서는 배열이 값으로 전달되었는지 또는 Java에서 참조로 전달되었는지 확인하는 방법을 소개합니다.
이 페이지의 내용
Java는 모든 메서드 인수를 값으로 전달합니다. 인수가 배열이면 매개변수에 복사되는 값은 배열 객체를 가리키는 참조입니다. 따라서 호출자와 매개변수는 같은 객체를 가리킬 수 있지만 서로 다른 변수입니다. 그래서 요소를 변경하면 호출자에게도 변경 사항이 보이지만, 매개변수에 다른 배열을 대입해도 호출자의 변수는 바뀌지 않습니다.
Java가 인수를 전달하는 방식
참조는 객체 그 자체가 아니라 코드가 객체에 접근할 수 있게 하는 값입니다. 메서드는 그 참조 값의 복사본을 받습니다. 메서드가 호출되면 호출자의 배열 변수와 메서드 매개변수는 같은 배열 객체를 가리킵니다. Java는 배열 변수 자체를 참조로 전달하지 않으므로, 메서드가 자기 매개변수에 다른 값을 대입해도 호출자의 변수를 다른 배열로 바꿀 수 없습니다.
객체를 변경하는 것과 변수를 변경하는 것은 다릅니다. 배열 요소에 값을 대입하면 공유 객체가 바뀝니다. 매개변수에 값을 대입하면 그 매개변수에 복사된 참조만 바뀝니다. 두 작업 모두 호출된 메서드 안에서 이루어지지만 결과는 서로 다릅니다.
배열 요소 변경은 호출자에게 어떻게 보일까요?
메서드가 values[index]에 값을 쓰면 두 참조로 모두 접근할 수 있는 배열 객체의 요소가 바뀝니다. 메서드가 반환된 뒤 호출자도 변경된 요소를 확인할 수 있습니다. 참조는 값으로 전달되었지만, 복사된 참조가 여전히 같은 객체를 가리키므로 요소 변경이 보입니다.
메서드가 배열 매개변수에 새 배열을 대입하면 어떻게 될까요?
매개변수에 새 배열을 대입하면 그 매개변수는 다른 객체를 가리킵니다. 원래 배열을 계속 가리키는 호출자의 변수는 바뀌지 않습니다. 재대입 전에 원래 객체를 변경했다면 호출자도 그 변경을 확인할 수 있지만, 매개변수의 새 참조를 받지는 못합니다. 호출자의 배열 변수를 새 배열로 바꾸려면 새 배열을 반환하고 호출한 위치에서 반환값을 대입하거나 원래 배열을 직접 변경해야 합니다.
기본형 매개변수는 어떻게 동작할까요?
기본형 인수도 값으로 전달되므로 매개변수는 기본형 값의 복사본으로 시작합니다. 메서드에서 매개변수에 다른 숫자를 대입해도 호출자의 변수는 바뀌지 않습니다. 이는 배열 요소를 변경하는 경우보다 배열 매개변수에 새 배열을 대입하는 경우에 가깝습니다. 배열의 경우에는 참조가 추가로 관련됩니다. 복사된 참조로 공유 객체를 변경할 수 있지만, 새 참조를 대입하면 지역 매개변수만 영향을 받습니다.
다음은 단독으로 실행할 수 있는 예제입니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
public class ArrayArgumentDemo {
static void changeFirst(int[] values) {
values[0] = 9;
}
static void replaceParameter(int[] values) {
values = new int[] {7, 8};
}
static void changeNumber(int number) {
number = 9;
}
public static void main(String[] args) {
int[] numbers = {1, 2};
changeFirst(numbers);
System.out.println(numbers[0]);
replaceParameter(numbers);
System.out.println(numbers[0]);
int count = 1;
changeNumber(count);
System.out.println(count);
}
}
9
9
1
첫 번째 출력은 변경된 요소를 보여 줍니다. 두 번째 출력은 메서드 매개변수에 다른 배열을 대입한 뒤에도 호출자의 배열은 그대로임을 보여 줍니다. 마지막 출력에서는 호출자의 기본형 변수도 바뀌지 않은 것을 확인할 수 있습니다.
핵심 정리
Java는 배열 참조를 포함한 모든 인수를 값으로 전달합니다. 호출자와 메서드 매개변수가 같은 배열 객체를 가리키면 요소를 변경했을 때 그 결과가 보입니다. 매개변수에 새 참조를 대입하면 해당 매개변수만 바뀌고, 기본형 매개변수에 값을 대입하면 그 복사본만 바뀝니다. 객체 변경과 매개변수 대입을 구분하면 동작을 정확히 예측할 수 있습니다.