*본 게시물은 개인 공부를 기록하기 위해 작성하였으며, 내용에 오류가 있을 수 있음을 밝힙니다.
*본 게시물은 남궁성 강사님의 자바의 정석 교재를 참고하여 작성하였습니다.
Q) 첫 번째 코드와 두 번째 코드의 출력값이 각각 어떻게 나올까? 이유는 뭘까?
스크롤을 내려 글을 읽으시기 전에 먼저 스스로 답을 생각해 보시길 바랍니다.


<첫 번째 코드의 출력값>

<두 번째 코드의 출력값>

두 코드의 출력값이 다르게 나오는 이유는 change 메서드의 매개변수 타입이 다르기 때문이다.
-> 매개변수의 타입이 기본형일 때와 참조형일 때의 차이를 이해해야한다.
자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사하여 전달한다. 매개변수가 기본형이면 값 자체가 복사되어 전달되므로, 메서드 내에서 변경해도 원본 변수(인스턴스 변수 'd.x')에는 영향이 없다. 반면, 참조형의 경우에는 '값'이 아니라 '객체의 주소'가 복사되어 전달되기 때문에, 메서드 내에서 객체의 상태를 변경하면 원본 객체에도 반영된다.
기본형 매개변수를 가지는 change메서드가 포함된 첫 번째 예시 코드
1. 우선 코드를 실행하면 main 메서드를 읽는다. main 메서드 내에서 Data 타입의 Data 객체를 생성하고 참조변수 d가 그 객체를 가리키게 된다.
2. d.x = 10에서는 위에서 생성한 객체의 x값을 10으로 초기화한다.
3. change(d.x)에서 change메서드가 호출되면 d.x가 change메서드의 매개변수 x에 복사된다.
4. change메서드 내에서 x=1000을 읽으면 change메서드 내에서 x의 값을 1000으로 변경한다.
5. 다음 메서드인 println이 실행되면, change메서드가 종료되면서 매개변수 x(로컬 변수)는 스택에서 제거된다.
-> 이 경우에 인스턴스 변수 d.x의 값이 변경된 것이 아니라, change메서드 내에서만 존재하는 로컬 변수 x값이 변경된 것이다.
6. 따라서 d.x값을 출력하면 변경 전과 동일한 10이 나오게 된다.
참조형 매개변수를 가지는 change메서드가 포함된 두 번째 예시 코드
1. main 메서드를 읽고, Data 타입의 Data 객체 d를 생성한 후 인스턴스 변수 d.x를 10으로 초기화한다.
2. change(d)를 호출한다.
3. 이 코드에서의 change메서드는 매개변수가 기본형이 아니라 참조형이기 때문에 '값'이 아니라 '값이 저장된 주소'를 change메서드에 넘겨준 것이다.
-> 매개변수 d에 저장된 주소값으로 인스턴스 변수인 x에 접근이 가능해졌다!
4. change메서드 내에서 d.x=1000을 읽어서 인스턴스 변수 값을 10에서 1000으로 변경하였다.
5. 첫 번째 예시에서 change메서드 내의 로컬 변수만 변경한 것과 달리, 인스턴스 변수값을 변경하였으므로 change메서드가 종료되어 매개변수 d의 값이 스택에서 제거된 후에도 change메서드에서 변경한 값이 유효하다.
-> 첫 번째 예시 코드에서는 change메서드의 매개변수가 기본형이었기 때문에 변수 x에 '값 자체'를 복사만 해왔던 것과 달리, 이 두 번째 예시 코드에서는 change메서드의 매개변수가 참조형이기 때문에 변수 d에 '객체의 주소'가 저장되어 있다. 즉, main메서드의 참조변수 d와 change메서드의 참조변수 d는 같은 객체를 가리키게 된다. 따라서 change메서드의 매개변수 d로 그 객체를 참조하여 객체의 인스턴스 변수값을 변경할 수 있는 것이다.