소개
많은 자바 프로그래머들이 자바가 값에 의한 전달인지 아니면 참조에 의한 전달인지 의문을 품습니다. 이 기사는 왜 자바가 항상 값에 의한 전달인지에 대해 요약합니다.
먼저, 값에 의한 전달과 참조에 의한 전달이란 무엇을 의미할까요?
- 값에 의한 전달: 메서드 매개변수 값은 다른 변수로 복사되고 그 복사된 객체가 메서드에 전달됩니다. 메서드는 복사본을 사용합니다.
- 참조에 의한 전달: 실제 매개변수에 대한 별칭 또는 참조가 메서드에 전달됩니다. 메서드는 실제 매개변수에 액세스합니다.
이 용어들에 대한 혼란은 자바의 객체 참조 개념에서 비롯된 것입니다. 기술적으로 자바는 항상 값에 의한 전달입니다. 왜냐하면 변수가 객체에 대한 참조를 보유하더라도 해당 객체 참조는 객체의 메모리 위치를 나타내는 값입니다. 따라서 객체 참조는 값에 의해 전달됩니다.
참조 데이터 유형과 기본 데이터 유형 모두가 값에 의해 전달됩니다. 자바에서의 데이터 유형에 대해 더 알아보세요.
데이터 유형을 이해하는 것 외에도 자바에서의 메모리 할당에 대한 이해가 중요합니다. 왜냐하면 참조 데이터 유형과 기본 데이터 유형은 다르게 저장되기 때문입니다.
값으로 전달하는 것을 보여주는 것
다음 예제는 자바에서 값이 전달되는 방법을 보여줍니다.
다음 예제 프로그램은 다음 클래스를 사용합니다:
public class Balloon {
private String color;
public Balloon() {}
public Balloon(String c) {
this.color = c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
다음 예제 프로그램은 두 변수를 교환하는 일반적인 메서드인 swap()
과 변수 값을 변경하려는 다른 메서드인 changeValue()
를 사용합니다.
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); // 메모리 참조 = 50
Balloon blue = new Balloon("Blue"); // 메모리 참조 = 100
swap(red, blue);
System.out.println("After the swap method executes:");
System.out.println("`red` color value = " + red.getColor());
System.out.println("`blue` color value = " + blue.getColor());
changeValue(blue);
System.out.println("After the changeValue method executes:");
System.out.println("`blue` color value = " + blue.getColor());
}
// 일반적인 교환 메서드
public static void swap(Object o1, Object o2){
Object temp = o1;
o1 = o2;
o2 = temp;
}
private static void changeValue(Balloon balloon) { // balloon = 100
balloon.setColor("Red"); // balloon = 100
balloon = new Balloon("Green"); // balloon = 200
balloon.setColor("Blue"); // balloon = 200
}
}
예제 프로그램을 실행하면 다음과 같은 출력이 생성됩니다:
OutputAfter the swap method executes:
'red' color value = Red
'blue' color value = Blue
After the changeValue method executes:
'blue' color value = Red
출력 결과는 swap()
메서드가 원래 객체의 색상 값을 교환하지 않았음을 보여줍니다. 이는 swap()
메서드가 원본 객체 참조 값의 사본에만 영향을 미치기 때문에 자바가 값으로 전달되는 것임을 보여줍니다.
이 swap()
메서드 테스트는 값으로 전달되는지 또는 참조로 전달되는지를 확인하기 위해 모든 프로그래밍 언어와 함께 사용할 수 있습니다.
예시 swap()
메서드 설명
클래스의 인스턴스를 생성하기 위해 new
연산자를 사용하면 객체가 생성되고 변수에는 객체가 저장된 메모리 위치가 포함됩니다.
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
다음은 swap()
메서드가 실행될 때 발생하는 단계별 세부사항입니다:
-
red
가 메모리 위치 50을 가리키고blue
가 메모리 위치 100을 가리키고, 이것들이 각각Balloon
객체의 메모리 위치임을 가정합니다. -
클래스가
red
와blue
변수를 인수로 하여swap()
메서드를 호출하면, 두 개의 새로운 객체 변수인o1
과o2
가 생성됩니다.o1
과o2
는 각각 메모리 위치 50과 100을 가리킵니다. -
다음 코드 스니펫은
swap()
메소드 내에서 무슨 일이 발생하는지 설명합니다:public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100 Object temp = o1; // o1의 객체 참조 값을 temp에 할당: temp = 50, o1 = 50, o2 = 100 o1 = o2; // o2의 객체 참조 값을 o1에 할당: temp = 50, o1 = 100, o2 = 100 o2 = temp; // temp의 객체 참조 값을 o2에 할당: temp = 50, o1 = 100, o2 = 50 } // 메소드 종료
-
o1
과o2
의 값이 교환되지만, 이 값들은red
와blue
메모리 위치의 사본이기 때문에red
와blue
색상 값에는 변경이 없습니다.
변수는 객체에 대한 참조를 포함하고 있으므로 참조를 전달하고 Java가 참조에 의한 전달을 수행한다고 가정하는 것은 흔한 실수입니다. 그러나 실제로 전달되는 것은 참조의 사본인 값이며, 따라서 값에 의한 전달입니다.
changeValue()
메서드 예제 설명
예제 프로그램에서 다음 메소드는 blue
변수가 참조하는 객체의 색상 값을 변경합니다:
private static void changeValue(Balloon balloon) { // balloon = 100
balloon.setColor("Red"); // balloon = 100
balloon = new Balloon("Green"); // balloon = 200
balloon.setColor("Blue"); // balloon = 200
}
changeValue()
메소드 내에서 일어나는 일들의 단계별 분석입니다:
-
클래스는 메모리 위치 100을 참조하는
blue
변수에changeValue()
메소드를 호출합니다. 첫 번째 줄은 메모리 위치 100을 가리키는 참조를 생성합니다. 메모리 위치 100에 있는 객체의 색상 값은"Red"
로 변경됩니다. -
두 번째 줄은 새 객체(색상 값
"Green"
)를 생성합니다. 새 객체는 메모리 위치 200에 있습니다.balloon
변수에 실행된 모든 추가 메소드는 메모리 위치 200에 있는 객체에 작용하며, 메모리 위치 100에 있는 객체에는 영향을 미치지 않습니다. 새balloon
변수는 1번 줄에서 생성된 참조를 덮어쓰고, 이 메소드 내에서 1번 줄의balloon
참조는 더 이상 접근할 수 없습니다. -
세 번째 줄은 메모리 위치 200에 있는 새
Balloon
객체의 색상 값을"Blue"
로 변경하지만, 메모리 위치 100에 있는blue
에 의해 참조되는 원본 객체에는 영향을 주지 않습니다. 이것이 예제 프로그램 출력의 마지막 줄이blue color value = Red
를 출력하는 이유입니다. 이는 첫 번째 줄에서의 변경을 반영합니다.
결론
이 글에서는 자바가 값을 전달하는 이유에 대해 배웠습니다. 더 많은 자바 튜토리얼로 학습을 이어나가세요.
Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference