자바에서는 항상 pass-by-value (값에 의한 전달) 메커니즘을 사용하지만, 객체에 대해서는 특이점이 있습니다:
따라서 메서드 내부에서 객체의 필드를 변경하면 원래 객체에 반영되지만, 메서드 내에서 새로운 참조를 변수에 할당하려고 하면 원본 객체에는 영향을 미치지 않습니다. 이것은 종종 pass-by-reference와 혼동되지만 자바는 pass-by-reference를 지원하지 않습니다!
예제:
void changePrimitive(int a) { a = 10; } void changeObject(Point p) { p.x = 10; } int num = 5; changePrimitive(num); // num은 여전히 5 Point pt = new Point(1, 2); changeObject(pt); // 이제 pt.x == 10
중요! 메서드 내에서 p = new Point(100, 200)과 같이 할당하면 메서드 외부의 원래 객체는 변경되지 않습니다. 객체의 필드만 변경되고, 그 참조는 변경되지 않습니다!
질문: 메서드에서 전달된 객체를 변경하여 메서드 외부에서 참조 변수가 새 객체를 가리키게 할 수 있습니까?
답변: 아니요, 할 수 없습니다. 메서드 내부에서 새 참조를 인수에 할당할 때 이는 메서드 종료 후 사라지는 참조의 복사본에만 영향을 미칩니다. 메서드 외부에서 인수 변수는 이전 객체를 가리킵니다.
void reassign(Point p) { p = new Point(100, 200); // 오직 로컬에서만! } Point pt = new Point(5, 5); reassign(pt); // pt는 여전히 (5, 5)
이야기
대규모 금융 시스템에서 API가 메서드 내에서 참조를 수정하여 객체에 대한 변경을 "반환"하는 방식으로 구현되었습니다. 결과적으로 메서드 종료 후 변경 사항이 반영되지 않았습니다. 객체의 변형과 새로운 객체의 반환을 명확히 구분하기 위해 논리의 일부를 완전히 재설계해야 했습니다.
이야기
두 객체의 교환을 위해
swap(A a, B b)메서드로 스왑을 구현하려고 할 때, 개발자는 참조를 전달하고 메서드 내에서 교환했습니다. 이것은 작동하지 않았습니다. 결과를 반환하거나 배열 컨테이너를 사용해야 했습니다. 값에 의한 전달에 대한 이해 부족이 객체 교환의 오류를 초래했습니다.
이야기
한 프로젝트 참가자가 C++에서 논리를 마이그레이션하면서 pass-by-reference의 동작을 예상했습니다. 결과적으로 메서드 내부의 변경 사항이 "나타나지" 않았습니다. 코드의 중요한 부분을 긴급하게 다시 작성해야 했으며, 이는 상당한 시간을 소모했습니다.