πŸ“‚ JAVA/μ£Όμš” κ°œλ…

얕은 볡사(Shallow Copy) vs κΉŠμ€ 볡사(Deep Copy)

Amenable 2023. 4. 7. 21:41

  얕은 볡사(Shallow Copy)λž€ μ£Όμ†Œκ°’μ„ λ³΅μ‚¬ν•˜λŠ” 것을 λ§ν•œλ‹€. (μŠ€νƒ μ˜μ—­)

  κΉŠμ€ 볡사(Deep Copy)λž€ μ‹€μ œ 값을 λ©”λͺ¨λ¦¬ 곡간에 λ³΅μ‚¬ν•˜λŠ” 것을 λ§ν•œλ‹€. (νž™ μ˜μ—­)

 

1. 얕은 볡사(Shallow Copy) 🐝

  얕은 볡사(Shallow Copy)λŠ” μ£Όμ†Œκ°’μ„ λ³΅μ‚¬ν•˜λŠ” 것이닀. 참쑰값을 λ³΅μ‚¬ν–ˆκΈ° λ•Œλ¬Έμ— μœ„μ˜ 그림처럼 같은 μΈμŠ€ν„΄μŠ€λ₯Ό 가리킀고 μžˆλ‹€. κ·Έλž˜μ„œ 기쑴의 값을 λ°”κΎΈλ©΄ λ³΅μ‚¬λœ 값도 λ°”λ€Œκ²Œ λ˜λŠ” 상황이 λ°œμƒν•œλ‹€. 

public class User {
	String name;
	int age;
	
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}

----------

public class ShallowCopy {

	public static void main(String[] args) {
		User userA = new User("amenable", 24);
		User userB = userA;
		
		System.out.println(userA.name); // amenable
		System.out.println(userB.name); // amenable
		
		userA.name = "sunny"; // useA의 name만 λ°”κΎΌ 상황
		System.out.println(userA.name); // sunny
		System.out.println(userB.name); // sunny
	}
}

  이λ₯Ό μ˜λ„ν•œ 것이라면 상관이 μ—†μ§€λ§Œ μš°λ¦¬κ°€ 일반적으둜 μƒκ°ν•˜λŠ” κ²ƒμ²˜λŸΌ λ³΅μ‚¬λœ 값이 κΈ°μ‘΄ 값에 μ˜ν•΄ 영ν–₯을 λ°›μ§€ μ•ŠμœΌλ €λ©΄ κΉŠμ€ 볡사λ₯Ό ν•΄μ•Ό ν•œλ‹€.

 

2. κΉŠμ€ 볡사(Deep Copy) 🐞

  κΉŠμ€ 볡사(Deep Copy)λŠ” μ‹€μ œ 값을 λ©”λͺ¨λ¦¬ 곡간에 λ³΅μ‚¬ν•˜λŠ” 것이닀. λ³΅μ‚¬λœ 값은 κΈ°μ‘΄ κ°’μ˜ 변경에 영ν–₯을 λ°›μ§€ μ•ŠλŠ”λ‹€. κΉŠμ€ 볡사λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법은 3κ°€μ§€κ°€ μ‘΄μž¬ν•œλ‹€.

1. 볡사 μƒμ„±μž λ˜λŠ” 볡사 νŒ©ν„°λ¦¬λ₯Ό μ΄μš©ν•˜λŠ” 방법

public class User {
	String name;
	int age;
	
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	// 볡사 μƒμ„±μž
	public User(User user) {
		this.name = user.name;
		this.age = user.age;
	}
	
	// 볡사 νŒ©ν„°λ¦¬
	public static User copyFactory(User user) {
		User copyUser = new User(user.name, user.age);
		return copyUser;
	}
}

----------

public class DeepCopy {

	public static void main(String[] args) {
		User userA = new User("amenable", 24);
		User userB = new User(userA);
		User userC = User.copyFactory(userA);
		
		System.out.println(userA.name); // amenable
		System.out.println(userB.name); // amenable
		System.out.println(userC.name); // amenable
		
		userA.name = "sunny";
		userB.name = "immortal";
		
		System.out.println(userA.name); // sunny
		System.out.println(userB.name); // immortal
		System.out.println(userC.name); // amenable
	}
}

2. 직접 객체λ₯Ό μƒμ„±ν•˜μ—¬ λ³΅μ‚¬ν•˜λŠ” 방법

public class DeepCopy {

	public static void main(String[] args) {
		User userA = new User("amenable", 24);
		User userB = new User(userA.name, userA.age);
		
		System.out.println(userA.name); // amenable
		System.out.println(userB.name); // amenable
		
		userA.name = "sunny";
		
		System.out.println(userA.name); // sunny
		System.out.println(userB.name); // amenable
	}
}

3. Cloneable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ clone() ν•¨μˆ˜λ₯Ό μ˜€λ²„λΌμ΄λ”©ν•˜μ—¬ λ³΅μ‚¬ν•˜λŠ” 방법

public class User implements Cloneable {
	String name;
	int age;
	
	public User(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	@Override
	public User clone() throws CloneNotSupportedException {
		return (User) super.clone();
	}
}

----------

public class DeepCopy {

	public static void main(String[] args) throws CloneNotSupportedException {
		User userA = new User("amenable", 24);
		User userB = userA.clone();
		
		System.out.println(userA.name); // amenable
		System.out.println(userB.name); // amenable
		
		userA.name = "sunny";
		
		System.out.println(userA.name); // sunny
		System.out.println(userB.name); // amenable
	}
}

  'clone μž¬μ •μ˜λŠ” μ£Όμ˜ν•΄μ„œ μ§„ν–‰ν•˜λΌ- μ΄νŽ™ν‹°λΈŒ μžλ°”μ˜ ITEM13'(κΈ€1, κΈ€2)에 λ”°λ₯΄λ©΄ clone() μž¬μ •μ˜λŠ” final μΈμŠ€ν„΄μŠ€ λ˜λŠ” 배열이 μ•„λ‹Œ 경우 μ‚¬μš©μ„ κΆŒν•˜μ§€ μ•ŠλŠ”λ‹€λΌκ³  ν•œλ‹€. κ·ΈλŸ¬λ―€λ‘œ κΉŠμ€ λ³΅μ‚¬λŠ” clone이 μ•„λ‹Œ λ‹€λ₯Έ λ°©λ²•을 μ΄μš©ν•˜λ„둝 ν•˜μž.

 

ν•΄λ‹Ή 글은
μž­μ½”λ”© λ‹˜μ˜ 'Shallow copy(얕은 볡사) vs Deep Copy(κΉŠμ€ 볡사)',
μ΅œλΈ”λž™ λ‹˜μ˜ '[Java] Shallow copy와 Deep copy',
을 μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.