[JAVA] 얕은 복사, 깊은 복사
얕은 복사(Shallow Copy)
public class Employee {
private String empNum;
private String name;
private int age;
Public Employee();
public Employee(String empNum, String name, int age){
this.empNum = empNum;
this.name = name;
this.age = age;
}
public String getEmpNum(){
return this.empNum;
}
public void setEmpNum(String num){
this.empNum = num;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return this.age;
}
public void setAge(int age){
this.age = age;
}
}
사원의 정보를 담는 Employee 클래스가 있다.
그리고 이 클래스들을 담는 list가 있다.
List<Employee> empList = new ArrayList<>();
empList.add(new Employee('20231229','Enna', 25));
empList.add(new Employee('20231229','Ann', 26));
empList.add(new Employee('20231229','Lily', 27));
//해당 list를 복사
List<Employee> copyEmpList;
copyEmpList = empList;
copyEmpList.get(0).setName('Test');
System.out.println(empList.get(0).getName());
System.out.println(copyEmpList.get(0).getName());
위와 같이 list를 복사할 경우 두 리스트는 서로 독립적인 개체지만 리스트 내부의 Employee객체는 동일하기 떄문에 실행 결과는 다음과 같다.
Test
Test
empList와 copyEmpList의 각 Employee 객체는 동일한 메모리 주소를 가리키기 때문에, 한 리스트에서 객체를 수정하면 다른 리스트의 같은 객체도 변경이 된다.
즉 얕은 복사는 실제 값이 아닌, 값을 가리키는 “주소”를 복사해 같은 객체를 가리키는 것을 뜻 한다.
깊은 복사(Deep Copy)
깊은 복사는 주소값이 아닌 실제 값을 복사하는것을 뜻한다.
생성자와 팩터리를 이용하여 깊은 복사를 진행한다.
public class Employee {
private String empNum;
private String name;
private int age;
public Employee();
public Employee(String empNum, String name, int age){
this.empNum = empNum;
this.name = name;
this.age = age;
}
// 복사 생성자
public Employee(Employee original){
this.empNum = original.getEmpNum();
this.name = original.getName();
this.age = original.getAge();
}
// 복사 팩터리
public static Employee copy(Employee original){
Employee copyObject = new Employee();
copyObject.empNum = original.getEmpNum();
copyObject.name = original.getName();
copyObject.age = original.getAge();
return copyObject; // 반환값 추가
}
public String getEmpNum(){
return this.empNum;
}
public void setEmpNum(String num){
this.empNum = num;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return this.age;
}
public void setAge(int age){
this.age = age;
}
}
List<Employee> empList = new ArrayList<>();
empList.add(new Employee('20231229','Enna', 25));
empList.add(new Employee('20231229','Ann', 26));
empList.add(new Employee('20231229','Lily', 27));
// 해당 list를 복사
List<Employee> copyEmpList = new ArrayList<>(); // 리스트 초기화
List<Employee> factoryCopyEmpList = new ArrayList<>(); // 리스트 초기화
// 복사 생성자를 사용하여 깊은 복사 수행
for(Employee emp : empList){
copyEmpList.add(new Employee(emp));
}
// 복사 팩터리를 사용하여 깊은 복사 수행
for(Employee emp : empList){
factoryCopyEmpList.add(Employee.copy(emp));
}
copyEmpList.get(0).setName("Test");
System.out.println(empList.get(0).getName());
System.out.println(copyEmpList.get(0).getName());
System.out.println(factoryCopyEmpList.get(0).getName());
실행결과는 다음과 같다.
Enna
Test
Enna
원본은 그대로 Enna, 복사하고 수정한 copyEmpList는 Test, 원본의 값을 복사해놓은 factoryCopyEmpList는 그대로 Enna이다.
실제로 세 값의 주소를 출력해 보면 세 값의 주소가 모두 다르기 때문에 복사한 리스트의 객체의 값을 수정해도 원본의 값음 바뀌지 않는다.