참조에 의한 호출
변수의 메모리 주소를 직접 전달하는 것
만약에 전달받은 값을 변경한다면? 원본도 같이 변경된다.
값에 의한 호출
변수에 저장된 값을 그대로 복사하여 전달하는 것
만약에 메소드 내에서 전달받은 값을 변경한다면? 메소드 안에서만 변경되고, 원래 전달된 값은 변경되지 않는다.
자바에서는 두 가지 데이터형으로 분류할 수 있는데,
기본형은 값 그대로가 전달되는 것이고, 참조형은 주소값이 전달되는 것이다.
결국에 둘 다 값을 전달하는 것이 된다.
그래서 자바에서는 Call by Value를 사용한다고 하는 것이다.
원시값이 복사되느냐 주소값이 복사되느냐 둘 중 하나이기 때문!
이때 참조형을 전달할 때 왜 Call by Value일까
예시를 들어보자
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
// StringBuilder 객체를 메서드에 전달
System.out.println("Before modify: " + sb);
modifyStringBuilder(sb); // 객체의 내용 수정
System.out.println("After modify: " + sb); // 객체의 내용이 수정됨
}
public static void modifyStringBuilder(StringBuilder sb) {
sb.append(", World!"); // StringBuilder 내부 수정
sb = new StringBuilder("Goodbye"); // 새로운 객체 할당, 원본 객체에는 영향 없음
}
}
> Output
Before modify: Hello
After modify: Hello, World!
StringBuilder는 참조 타입
sb
의 원본 객체의 주소값이 modifyStringBuilder
에 전달된다.
이때, 주소값 자체가 복사되어서 전달된다.
그래서 메소드 내에서 객체를 변경할 수는 있지만, 기존의 주소값 자체는 변경할 수 없게 되는 것
위 코드처럼 메소드 내에서 sb
를 새로운 객체로 할당하려고 해도 원본 객체가 변경되지 않고 "Hello, World"가 출력되는 것을 볼 수 있다.
자바는 Call by Value
객체의 주소값이 복사되어 전달되고, 객체의 상태 수정은 가능하지만? 주소값 자체를 바꿀 수는 없다는 것에서 Call by Value 방식으로 작동한다.