자바에서 변수에 값을 대입하는 것은 변수에 들어 있는 값을 복사해서 대입하는 것이다.
기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어 있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어 있는 참조값을 복사해서 대입한다.
int a = 10;
int b = a;
Student s1 = new Student();
Student s2 = s1;
기본형은 변수에 값을 대입하더라도 실제 사용하는 값이 변수에 바로 들어있기 때문에 해당 값만 복사해서 대입한다고 생각하면 된다. 그런데 참조형의 경우, 실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만 복사된다.
package ref;
public class VarChange1 {
public static void main(String[] args) {
int a = 10;
int b = a;
System.out.println("a = " + a);
System.out.println("b = " + b);
// a 변경
a = 20;
System.out.println("변경 a = 20");
System.out.println("a = " + a);
System.out.println("b = " + b);
// b 변경
b = 30;
System.out.println("변경 b = 30");
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
int a = 10;
int b = a;
✏️ 실행 결과
a = 10
b = 10
변수의 대입은 변수에 들어있는 값을 복사해서 대입한다. 여기서는 변수 a
에 들어있는 값 10
을 복사해서 변수 b
에 대입한다. 변수 a
자체를 b
에 대입하는 것이 아니다.
a = 20;
✏️ 실행 결과
a = 20
b = 10
변수 a
에 값 20
을 대입했다. 따라서 변수 a
의 값이 10
에서 20
으로 변경되었다. 변수 b
에는 아무런 영향을 주지 않는다.
b = 30;
✏️ 실행 결과
a = 20
b = 30
변수 b
에 값 30
을 대입했다. 변수 b
의 값이 10
에서 30
으로 변경되었다. 변수 a
에는 아무런 영향을 주지 않는다.
여기서 핵심은 int b = a;
라고 했을 때 변수에 들어있는 값을 복사해서 전달한다는 점이다. 따라서 a = 20
, b = 30
이라고 했을 때 각각 본인의 값만 변경되는 것을 확인할 수 있다.
Data
클래스를 만들자. 이 클래스는 int value
라는 멤버 변수를 가진다.
package ref;
public class Data {
int value;
}
package ref;
public class VarChange2 {
public static void main(String[] args) {
Data dataA = new Data();
dataA.value = 10;
Data dataB = dataA;
System.out.println("dataA 참조값 : " + dataA);
System.out.println("dataB 참조값 : " + dataB);
System.out.println("dataA.value : " + dataA.value);
System.out.println("dataB.value : " + dataB.value);
// dataA 변경
dataA.value = 20;
System.out.println("변경 dataA.value = 20");
System.out.println("dataA.value : " + dataA.value);
System.out.println("dataB.value : " + dataB.value);
// dataB 변경
dataA.value = 30;
System.out.println("변경 dataB.value = 30");
System.out.println("dataA.value : " + dataA.value);
System.out.println("dataB.value : " + dataB.value);
}
}
dataA
변수는 Data
클래스를 통해서 만들었기 때문에 참조형이다. 이 변수는 Data
형 객체의 참조값을 저장한다.
Data
객체를 생성하고, 참조값을 dataA
에 저장한다. 그리고 객체의 value
변수에 값 10
을 저장했다.
✏️ 실행 코드
Data dataA = new Data();
dataA.value = 10;
Data dataB = dataA;
System.out.println("dataA 참조값 : " + dataA);
System.out.println("dataB 참조값 : " + dataB);
System.out.println("dataA.value : " + dataA.value);
System.out.println("dataB.value : " + dataB.value);
✏️ 출력 결과
dataA 참조값 : ref.Data@30f39991
dataB 참조값 : ref.Data@30f39991
dataA.value : 10
dataB.value : 10
변수의 대입은 변수에 들어있는 값을 복사해서 대입한다. 변수 dataA
에는 참조값 x001
이 들어있다. 여기서는 변수 dataA
에 들어있는 참조값 x001
을 복사해서 dataB
에 대입한다. 참고로 변수 dataA
가 가리키는 인스턴스를 복사하는 것이 아니라, 변수에 들어있는 참조값만 복사해서 전달한다.
이제 dataA
와 dataB
에 들어있는 참조값은 같다. 따라서 둘 다 같은 x001
Data
인스턴스를 가리킨다.
✏️ 실행 코드
dataA.value = 20;
System.out.println("dataA.value : " + dataA.value);
System.out.println("dataB.value : " + dataB.value);
✏️ 출력 결과
dataA.value = 20
dataB.value = 20
dataA.value = 20
코드를 실행하면 dataA
가 가리키는 x001
인스턴스의 value
값을 10
에서 20
으로 변경한다. 그런데 dataA
와 dataB
는 같은 x001
인스턴스를 참조하기 때문에 dataA.value
와 dataB.value
는 둘 다 같은 값인 20
을 출력한다.
✏️ 실행 코드
dataB.value = 30;
System.out.println("dataA.value : " + dataA.value);
System.out.println("dataB.value : " + dataB.value);
✏️ 출력 결과
dataA.value = 30
dataB.value = 30
dataB.value = 30
코드를 실행하면 dataB
가 가리키는 x001
인스턴스의 value
값을 20
에서 30
으로 변경한다. 그런데 dataA
와 dataB
는 같은 x001
인스턴스를 참조하기 때문에 dataA.value
와 dataB.value
는 같은 값인 30
을 출력한다.
여기서 핵심은 Data dataB = dataA
라고 했을 때 변수에 들어있는 값을 복사해서 사용한다는 점이다. 그런데 그 값이 참조값이다. 따라서 dataA
와 dataB
는 같은 참조값을 가지게 되고, 두 변수는 같은 객체 인스턴스를 참조하게 된다.
💡 출처