배열 복사에 대해 정리해보겠습니다.
//커피 1호점
String[] coffee = new String [3];
coffee[0] = "아이스 아메리카노";
coffee[1] = "복숭아 아이스티";
coffee[2] = "말차 프라푸치노";
System.out.println("----------coffee 메뉴 출력----------");
for (int i = 0; i < coffee.length; i++) {
System.out.println(coffee[i]);
}

길이가 3인 coffee라는 배열을 생성
커피 1호점이라고 생각하자
1호점에는 아아,라떼,말차를 판매하고 있다
2호점 가게를 내려고하는데 2호점에는 1호점과 똑같은 메뉴를 판매할 계획임
//커피 2호점 : 1호점과 똑같은 커피 판매
String[] coffee2 = coffee; //복사
System.out.println("----------coffee 메뉴 출력----------");
for(int i=0; i<coffee2.length; i++){
System.out.println(coffee2[i]);
}
이렇게 하면 1호점 메뉴를 따라만든 2호점이 생긴다
메뉴가 똑같은지 확인해보자

짠!
1호점 메뉴와 정확하게 일치한다
그런데 2호점 사장님이 말차 프라푸치노 메뉴를 딸기 프라푸치노로 변경한다고한다
말차 프라푸치노는 세번째 인덱스 이기 때문에 2번 인덱스를 수정하자
coffee2[2] = "딸기 프라푸치노";
System.out.println("----------coffee2 메뉴 출력----------");
for(int i=0; i<coffee2.length; i++){
System.out.println(coffee2[i]);
}

말차 프라푸치노 -> 딸기 프라푸치노
정상적으로 수정된 것을 확인할 수 있다
그럼 1호점에서는 말차 프라푸치노를 팔고 2호점에서는 딸기 프라푸치노를 팔겠지??
라는 생각을 하며 1호점 메뉴를 다시 출력해보자
System.out.println("----------coffee 메뉴 출력----------");
for(int i=0; i<coffee.length; i++){
System.out.println(coffee[i]);
}

.
.
.
.
.
.
.

??
1호점 메뉴는 수정한적이 없는데 왜 말차 프라푸치노에서 딸기 프라푸치노로 변경된 것인가!!
원리를 이해해보자
원리를 이해하기 위해서는 Stack영역과 Heap영역에 대해 알고 있어야 한다

coffee 는 메모리 상 어딘가의 주소를 기억하고 있는데 그 주소를 1000이라고 하겠다
coffee변수는 스택영역 1000번지를 기억하고 있고 1호점의 메뉴는 힙영역의 1000번지에 저장되어있는 셈이다
그런데 2호점을 내면서 coffee2 = coffee 를 선언하게 되었고
이렇게 선언된 coffee2도 coffee와 같은 주소인 1000번지를 기억하게 된 것이다
그렇게 되면 coffee2와 coffee는 같은 주소를 할당하고 있어서 coffee2의 값을 수정하면 coffee도 같이 바뀌게 되는 것이다!!
이와 같은 복사를 얕은복사(Shallow Copy) 라고 한다.
즉 얕은복사는 복사된 객체와 원본 객체가 메모리를 공유하여 변경이 서로 영향을 미치는 것 이다.
그렇다면 1호점과 다른 메뉴를 판매하려면 어떻게 해야할까
3호점을 오픈해보자
3호점은 복숭아 아이스티 대신에 레몬 아이스티를 판매하려고한다
//커피 3호점 : 1호점과 다른 메뉴 판매
String[] coffee3 = new String [coffee.length];
for(int i=0; i<coffee3.length; i++){
coffee3[i]=coffee[i];
}
coffee3[1]="레몬 아이스티";
System.out.println("----------coffee3 메뉴 출력----------");
for(int i=0; i<coffee3.length; i++){
System.out.println(coffee3[i]);
}
System.out.println("----------coffee 메뉴 출력----------");
for(int i=0; i<coffee.length; i++){
System.out.println(coffee[i]);
}

3호점은 2호점과 달리 메뉴를 복사할 때 new String[coffee.length] 를 사용하여 1호점의 메뉴갯수 만큼 복사 하였고
반복문을 실행하여 첫번째 메뉴부터 순서대로 메뉴를 복사했다.
그랬더니 1호점과 메뉴가 다르게 출력되었다
Why?? How??

coffee3을 생성하면서 어딘가의 주소를 기억하게 되고 그 주소를 2000이라고 하자
힙영역의 2000번지에는 1호점과 같이 3개의 공간이 있고 그 공간에 1호점과 같은 메뉴를 집어넣는 방식이다
그렇게 되면 coffee는 1000번지를 기억하게되고 coffee3은 2000번지를 기억하게 된다
그래서 3호점의 메뉴를 수정해도 1호점의 메뉴는 바뀌지 않는 것이다
이를 깊은 복사(Deep Copy) 라고 한다.
깊은 복사는 복사된 객체가 원본 객체와 독립적으로 동작하며 서로 영향을 미치지 않는다는 특징이 있습니다
정리하자면 얕은복사는
복사본이 원본 객체의 메모리 주소를 참조하고 있기 때문에
원본 객체와 복사본 간의 독립성이 보장되지 않는 복사 이고
깊은복사는
원본 객체의 값을 새로운 메모리 공간에 복사하여
복사본을 수정해도 원본 객체에는 영향을 미치지 않는 완전히 독립적인 객체가 되는것 이다
좀 이해하기 쉽도록 커피에 비유하여 정리해보았는데 어떠셨나요?
잘 이해가 되었다면 다행입니다
감사합니다

'Java' 카테고리의 다른 글
| [Project] 영화 데이터베이스 웹 페이지 제작 ( 1 ) (0) | 2024.05.31 |
|---|---|
| [Spring / JAVA] 의존성 주입 DI (Dependency Injection) (1) | 2023.10.24 |
| MVC Pattern (0) | 2023.10.23 |
| JSTL (1) | 2023.10.17 |