💡개요
리팩터링 2탄을 읽다가 JS의 얕은 복사 코드를 봤는데, 너무 어색하다.
자바에선 사용해본 적이 없는 문법이라서 그런 것 같다.
이게 뭔지 정리좀 해보자.
🛠️ 얕은 복사
자바스크립트의 얕은 복사란 객체나 배열을 복사할 때, 최상위 수준의 값만 복사하고 중첨된 객체나 배열은 참조값만 복사하는 방식이다.
..? 뭔 말이고.. 자바를 사용하는 난 난생 처음들어보는 문장이다.
쉽게 설명해보자면 int나 double, boolean 같은 기본 타입은 값 자체가 복사돼서 완전히 독립적인 복사본이 만들어진다.
반면, 배열이나 객체는 참조 타입이라서 얕은 복사를 하면 원본의 주소(참조)를 공유하게 된다.
⚙️ 기본 값 복사
let a = 10;
let b = a; // 값 복사
b = 20;
console.log(a); // 10 (영향 없음)
⚙️ 객체 복사 (참조 복사)
let original = { x: 1 }; // 객체 선언
let copy = original; // 참조 복사
copy.x = 99;
console.log(original.x); // 99 (같은 객체를 가리킴)
결국 배열이나 객체 내부의 또 다른 객체? 그럴 경우 참조 값만 복사하는 것이다.
물론 자바에도 얕은 복사가 있긴 하다.
class Address {
String city;
Address(String city) {
this.city = city;
}
}
class Person implements Cloneable {
String name;
Address address;
Person(String name, Address address) {
this.name = name;
this.address = address;
}
// 얕은 복사
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Address addr = new Address("Seoul");
Person p1 = new Person("Alice", addr);
Person p2 = p1.clone(); // 얕은 복사
p2.name = "Bob";
p2.address.city = "Busan"; // 내부 객체 변경
System.out.println(p1.name); // Alice
System.out.println(p1.address.city); // Busan ← 영향 받음!
}
}
여기서 드는 의문은 String도 참조형 타입인데??
맞다.
그런데 복사된 객체에게 영향을 받지 않는다.
그 이유는 String은 불변이기 때문이다.
String name = "Alice";
이렇게 문자열을 만들면, 내부적으로는 "Alice"라는 문자열이 String Constant Pool에 저장되고, name은 그 객체를 참조한다.
그런데 p2.name = "Bob";을 하면
- "Bob"이라는 새로운 문자열 객체가 생성되고
- p2.name은 이제 "Bob"을 가리킵니다.
- p1.name은 여전히 "Alice"를 가리키기 때문에 영향을 받지 않는다.
그.. 정리하면서도 잘 모르겠다.
근데 자바에선 예기치 않게 값이 변경될 수 있기 때문에 얕은 복사는 잘 사용하지 않는다고 한다.
'개발 일기' 카테고리의 다른 글
[개발 일기] 2025.05.24 - REST API의 URL에 대한 개인적인 생각 (0) | 2025.05.24 |
---|---|
[개발 일기] 2025.05.23 - LocalDateTime vs Long (에포크 타임) (0) | 2025.05.23 |
[개발 일기] 2025.05.21 - 점진적인 개선 (Feat : 클린코드) (0) | 2025.05.21 |
[개발 일기] 2025.05.20 - XSS (0) | 2025.05.20 |
[개발 일기] 2025.05.19 - ConcurrentHashMap이 HashMap보다 빠른 이유 (1) | 2025.05.19 |