멘토링
Deep, Shallow and Lazy Copy
langsamUndStetig
2022. 6. 17. 18:39
Shallow copy (얕은 복사)
얕은 복사는 참조값을 다른 새로운 변수에 넣어줌으로써 간단하게 실험해볼 수 있다.
이렇게 할 경우, 객체의 주소를 참조한 다른 변수에서 실제 객체의 값을 변경해버릴 수 있다.
public class Main {
public static void main(String[] args) {
int[] arr = {2, 3, 5};
int[] var = arr;
System.out.println(arr[0]); // 2
var[0] = 4; // var의 인덱스 0번 값 변경
System.out.println(arr[0]); // 출력값 4, 즉 arr의 값에 영향을 주었음
System.out.println(arr.equals(var)); // true
System.out.println(arr.hashCode()); // arr과 var은 hashCode()마저 동일함
System.out.println(var.hashCode());
}
}
깊은 복사
깊은 복사는 같은 값을 가진 동일한 객체를 하나 더 생성해서, 변수에 참조값을 할당하는 것이다.
즉, 하나의 객체를 다루는 얕은 복사와 달리, 개별적인 객체를 다루는 것을 말한다.
package basic;
import java.util.Arrays;
public class Main {
private int[] data;
public Main(int[] values) {
data = new int[values.length];
for (int i = 0; i < values.length; i++) {
data[i] = values[i];
}
}
public void showData() {
System.out.println(Arrays.toString(data));
}
public static void main(String[] args) {
int[] vals = {3, 5, 6};
Main m = new Main(vals); // {3, 5, 6}
System.out.println(vals.hashCode()); // 2003749087
System.out.println(m.hashCode()); // 1324119927
System.out.println(vals); // [I@776ec8df
System.out.println(m); //basic.Main@4eec7777
m.showData(); // {3, 5, 6}
vals[0] = 2; // {2, 5, 6}
m.showData(); // {3, 5, 6}
System.out.println(Arrays.toString(vals));
System.out.println(vals.hashCode());
System.out.println(m.hashCode());
}
}
Lazy Copy
이 방법은 얕은 복사와 깊은 복사가 혼합한 형태라고 한다. 이것의 작동방식은 먼저 빠른 얕은 복사를 사용하는 것이다. 그리고 counter를 이용해서 한 데이터를 얼마나 많은 객체들이 공유하는지 추적한다. 그래서 한 객체를 변경할 때, counter를 검사하여, 데이터 공유를 확인하고 필요시 깊은 복사를 할 수 있다.
Lazy copy는 깊은 복사처럼 보이지만, 가능한 경우엔 얕은 복사를 사용해서 속도의 이점이 있다. 단점은 다소 높지만 일정한 카운터에 의해 발생하는 기본 코스트다. 또한 특정 상황에선 순환참조가 문제를 일으킬 수 있다고 한다.
public class Main {
public static void main(String[] args) {
int a = 2; // 기본타입에서 얕은 복사는 깊은 복사처럼 작동한다.
int b = a;
b = 3;
System.out.println(a);
System.out.println(b);
String c = "Ho"; // String 타입도 마찬가지로 깊은 복사처럼 작동한다.
String d = c;
d = "Hello";
System.out.println(c);
System.out.println(d);
String h = new String("Ho");
String e = h;
e = new String("Hello");
System.out.println(h);
System.out.println(e);
}
}
참고 자료
https://www.geeksforgeeks.org/deep-shallow-lazy-copy-java-examples/