설명을 시작하기에 앞서
자바의 경우 Call by reference가 없이
Call by value 방식으로만 동작합니다.
'값' 을 넘겨주는 호출 방식을 Call by Value,
이 변수의 '참조값'(혹은 주소&포인터)를 넘겨주는 호출 방식을 Call by Reference 라고 합니다.
자바는 Call by Value 방식으로 동작하게 됩니다.
class Color {
String name;
public Color(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
@DisplayName("reference test")
@Test
void reference() {
// given
Color 빨강 = new Color("빨강");
// when
changeColor(빨강);
// then
assertThat(빨강.getName()).isEqualTo("파랑");
}
private void changeColor(Color color) {
color.setName("파랑");
}
위의 코드의 결과는 어떻게 될까요?
changeColor 메서드 내에서 이름을 바꾸니 원본 값도 함께 수정이 되었습니다. 이것은 복사가 이뤄지지 않았다는 거 같은데요?
Java에서는 객체를 메소드 인자로 넘길 때 참조하고 있는 지역 변수를 가르키는 값을 새로운 지역 변수를 생성(복사)하여 가르키게 합니다.
때문에 메서드 내에서 새로운 객체를 생성하여 가르키게 하더라도 호출을 한 원본에 대해서는 아무런 변경이 일어나지 않는 것이죠.
위의 예시에서도 들었던 주소값 출력은 결국 메서드 인자의 값이 아닌 가르키고 있는 값이었던 것으로 생각할 수 있을거 같군요!
위의 예시에서도 들었던 주소값 출력은 결국 메서드 인자의 값이 아닌 가르키고 있는 값이었던 것으로 생각할 수 있을거 같군요!
@DisplayName("pass-by-value")
@Test
void passByValue() {
// given
Color 빨강 = new Color("빨강");
Color 빨강_복제 = 빨강;
// when
newColor(빨강);
// then
assertThat(빨강.getName()).isEqualTo("빨강");
assertThat(빨강 == 빨강_복제).isTrue();
}
private void newColor(Color color) {
color = new Color("파랑");
}
결과는 어떨까요?
바뀌지 않는 검증에 대하여 테스트가 성공하였습니다. 즉 객체를 생성해서 새로운 객체를 할당하더라도 원본에는 영향이 없네요.
추가로 빨강과 빨강 복제를 ==(동일 비교) 하였는데도 결과가 true 입니다. 즉 어떠한 값도 할당 되지 않았어요.
자바의 정렬은 반환없이 다 void 입니다. 그런데 value인데 왜 reference처럼 작동해서 처리가 될까요?
java에서는 Call-by-Reference 방식을 직접적으로 지원하지는 않습니다. Java에서는 모든 변수가 기본적으로 값을 저장하기 위한 공간을 갖고 있으며, 이 공간에는 해당 변수의 값이 직접 저장됩니다.
그렇기 때문에 Java에서는 Call-by-Value 방식으로만 인자를 전달할 수 있습니다.
하지만 Java에서는 객체를 다룰 때 참조(reference)를 사용합니다.
객체 변수에는 객체가 저장된 메모리 주소가 저장되며, 이 주소를 통해 객체에 접근할 수 있습니다.
따라서 객체 변수를 메서드의 인자로 전달할 때에는 객체의 참조 값이 복사되어 전달되기 때문에,
Call-by-Value 방식으로 인자가 전달됩니다.
하지만, 이렇게 전달된 참조 값으로 원본 객체를 수정할 수 있기 때문에,
Java에서는 이를 Call-by-Reference와 유사한 효과를 얻는 방법으로 사용할 수 있습니다.
따라서 Java에서는 Call-by-Value 방식으로만 인자를 전달하지만,
객체의 참조 값으로 인해 Call-by-Reference와 유사한 동작을 할 수 있습니다.
참조 사이트
Java의 Call by value, Call by reference
[Java/자바] - 메서드 호출 방식(Call by Value / Call by Reference)