기술 면접 예상 질문 - 값 형식과 참조 형식의 차이에 대해 설명해주세요
값 형식과 참조 형식은 저장되는 메모리 영역과 데이터를 복사 방법에서 차이가 있습니다.
값 형식의 변수는 데이터를 저장할 때 데이터의 복사본을 만들어서 변수에 직접 저장합니다 이떄 기존 데이터와 복사한 데이터는 더 이상 아무런 연결점이 없고 변수는 선언된 메모리 영역 즉, 지역 변수라면 스택, 클래스의 멤버라면 힙 메모리 영역에 저장됩니다.
참조 형식의 변수는 데이터를 저장할 떄 힙 영역에 데이터를 저장하고 해당 데이터의 주소값을 변수에 저장해서 참조하게 됩니다. 즉 얕은 복사를 하게됩니다. 이때 기존 데이터와 새로 참조한 데이터는 같은 객체를 참조합니다.
이때 만약 참조 형식의 데이터를 기존 데이터와 같은 값들을 복사하여 독립적인 객체를 생성하고 싶다면 메서드를 통해서 데이터를 깊은 복사를 할 수 있습니다.
예시 코드
public class ABCD
{
int A;
int B;
public ABCD(int v1, int v2)
{
A = v1;
B = v2;
}
public ABCD(ABCD copy)
{
A = copy.A;
B = copy.B;
}
}
public static void Main()
{
int C = 10;
int D = 10;
ABCD classE = new ABCD(10,10);
// int C,D는 값 형식의 데이터를 스택영역에 저장하고 있습니다.
// ABCD classE는 참조 형식으로 데이터를 힙에 할당하고 참조합니다.
// int classE.A, classE.B는 값 형식의 데이터이지만 객체 내부의 필드여서 힙 영역에 저장하고 있습니다.
// 여기서 스택영역에는 int C, int D, ABCD classE 변수가 존재하게 되고
// 이떄 ABCD classE는 힙 영역을 참조하고 있습니다.
// 여기서 classE가 참조중인 힙 영역에는 new로 할당한 ABCD의 실제 데이터 int A, int B기 존재합니다.
ABCD classG = classE;
// 여기서 새로운 classG를 선언합니다.
// 여기서 스택영역에 ABCD classG 변수가 추가됩니다.
// 힙 영역에는 아무런 데이터가 추가되지 않습니다.
// classG는 classE가 참조하고 있던 힙 영역의 데이터를 그대로 참조합니다.
// 이것이 `얕은 복사` 상황 입니다.
ABCD classH = new ABCD(classE);
// 여기서 새로운 classH를 선언합니다
// 여기서 스택영역에 ABCD classH 변수가 추가됩니다
// classE.CopyABCD()를 통해서 classE와 모든 값이 똑같은 새로운 ABCD temp가 생성됩니다.
// 힙영역에 ABCD temp의 실제데이터가 추가됩니다.
// 변수 classH는 힙 영역에 있는 temp를 참조합니다.
// 이렇게 되면 classE와 classH는 더 이상 아무런 연결점이 없지만
// 현 상황에서는 같은 값을 가집니다 이것이 `깊은 복사` 상황입니다.
}