Call by reference / Call by value

allnight5·2023년 3월 20일
0

기술공부

목록 보기
2/33

설명을 시작하기에 앞서
자바의 경우 Call by reference가 없이
Call by value 방식으로만 동작합니다.

'값' 을 넘겨주는 호출 방식을 Call by Value,
이 변수의 '참조값'(혹은 주소&포인터)를 넘겨주는 호출 방식을 Call by Reference 라고 합니다.
자바는 Call by Value 방식으로 동작하게 됩니다.

1. Call by reference

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에서는 객체를 메소드 인자로 넘길 때 참조하고 있는 지역 변수를 가르키는 값을 새로운 지역 변수를 생성(복사)하여 가르키게 합니다.

때문에 메서드 내에서 새로운 객체를 생성하여 가르키게 하더라도 호출을 한 원본에 대해서는 아무런 변경이 일어나지 않는 것이죠.

위의 예시에서도 들었던 주소값 출력은 결국 메서드 인자의 값이 아닌 가르키고 있는 값이었던 것으로 생각할 수 있을거 같군요!

위의 예시에서도 들었던 주소값 출력은 결국 메서드 인자의 값이 아닌 가르키고 있는 값이었던 것으로 생각할 수 있을거 같군요!

2. Call by value

 @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)

profile
공부기록하기

0개의 댓글