기본형과 참조형이 메서드 호출에 따라서 어떻게 달라지는지 알아보자.
📚 대원칙 : 자바는 항상 변수의 값을 복사해서 대입한다.
자바에서 변수에 값을 대입하는 것은 변수에 들어있는 값을 복사해서 대입하는 것이다.
기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어 있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어있는 참조값을 복사해서 대입한다.
메서드를 호출할 때 사용하는 매개변수(파라미터)도 결국 변수일 뿐이다. 따라서 메서드를 호출할 때 매개변수에 값을 전달하는 것도 앞서 설명한 내용과 같이 값을 복사해서 전달한다.
package ref;
public class MethodChange1 {
public static void main(String[] args) {
int a = 10;
System.out.println("메서드 호출 전: a = " + a);
changePrimitive(a);
System.out.println("메서드 호출 후: a = " + a);
}
static void changePrimitive(int x) {
x = 20;
}
}
메서드를 호출할 때 매개변수 x
에 변수 a
의 값을 전달한다. 이 코드는 다음과 같이 해석할 수 있다.
int x = a;
자바에서 변수에 값을 대입하는 것은 항상 값을 복사해서 대입한다. 따라서 변수 a
, x
각각 숫자 10
을 가지고 있다.
메서드 안에서 x = 20
으로 새로운 값을 대입한다.
결과적으로 x
의 값만 20
으로 변경되고, a
의 값은 10
으로 유지된다.
메서드 종료 후 값을 확인해보면 a
는 10
이 출력되는 것을 확인할 수 있다. 참고로 메서드가 종료되면 매개변수 x
는 제거된다.
package ref;
public class MethodChange2 {
public static void main(String[] args) {
Data dataA = new Data();
dataA.value = 10;
System.out.println("메서드 호출 전: dataA.value = " + dataA.value);
changeReference(dataA);
System.out.println("메서드 호출 후: dataA.value = " + dataA.value);
}
static void changeReference(Data dataX) {
dataX.value = 20;
}
}
Data
인스턴스를 생성하고, 참조값을 dataA
변수에 담고 value
에 숫자 10
을 할당한 상태는 다음과 같다.
메서드를 호출할 때 매개변수 dataX
에 변수 dataA
의 값을 전달한다. 이 코드는 다음과 같이 해석할 수 있다.
Data dataX = dataA;
자바에서 변수에 값을 대입하는 것은 항상 값을 복사해서 대입한다. 변수 dataA
는 참조값 x001
을 가지고 있으므로 참조값을 복사해서 전달했다. 따라서 변수 dataA
, dataX
둘 다 같은 참조값인 x001
을 가지게 된다.
이제 dataX
를 통해서도 x001
에 있는 Data
인스턴스에 접근할 수 있다.
메서드 안에서 dataX.value = 20
으로 새로운 값을 대입한다.
참조값을 통해 x001
인스턴스에 접근하고 그 안에 있는 value
의 값을 20
으로 변경했다.
dataA
, dataX
모두 같은 x001
인스턴스를 참조하기 때문에 dataA.value
와 dataX.value
는 둘 다 20
이라는 값을 가진다.
메서드 종료 후 dataA.value
의 값을 확인해보면 다음과 같이 20
으로 변경된 것을 확인할 수 있다.
메서드 호출 전: dataA.value = 10
메서드 호출 후: dataA.value = 20
자바에서 메서드의 매개변수(파라미터)는 항상 값에 의해 전달된다. 그러나 이 값이 실제 값이냐, 참조(메모리 주소)값이냐에 따라 동작이 달라진다.
💡 출처