- Cloneable ์ธํฐํ์ด์ค ?
๋ณต์ ํด๋ ๋๋ ํด๋์ค์์ ๋ช ์ํ๋ ๋ฏน์ค์ธ ์ธํฐํ์ด์ค
๋ฏน์ค์ธ : ๋ค๋ฅธ ํด๋์ค์ ๋ถ๋ชจํด๋์ค๊ฐ ๋์ง ์์ผ๋ฉด์ ๋ค๋ฅธ ํด๋์ค์์ ์ฌ์ฉํ ์ ์๋ ๋ฉ์๋๋ฅผ ํฌํจํ๋ ํด๋์ค
'์์' ์ด ์๋ 'ํฌํจ'
public interface Cloneable {
}
- clone() ๋ฉ์๋ ?
java.lang.Object
protected native Object clone() throws CloneNotSupportedException;
-
Cloneable ์ธํฐํ์ด์ค๋ ๋น ์ธํฐํ์ด์ค !
๋ฐ๋ผ์ Cloneable ์ ๊ตฌํํ๋ค๊ณ clone() ์ ํธ์ถํ ์ ์๋ ๊ฒ์ด ์๋๋ค. -
clone() ๋ฉ์๋๋ ๋ฐ๋ก ์ค๋ฒ๋ผ์ด๋ฉ ํด์ค์ผ ํ๋ค ! ๋ clone() ์ ์ ๊ทผ์ ํ์๊ฐ protected ๋ผ์ ๊ฐ์ ํจํค์ง์์๋ง ์ ๊ทผ๊ฐ๋ฅ.
-
clone() ์ ๋ชจ๋ ํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋ฉ ํ ์ ์๋ค.
-
ํ์ง๋ง Cloneable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ง ์์ ํด๋์ค์ clone() ์ ์์ธ๋ฅผ ๋์ง๋ค !!
-
super.clone() ์ ์ฌ์ฉํ์ง ์์ ๊ฑฐ๋ผ๋ฉด, Cloneable ํ์ ์์.
-
Cloneable ์ ๊ตฌํํ ํด๋์ค๋ง clone() ์ ์ฌ์ฉํ ์ ์๋ค.
-
clone() ์ ์ค๋ฒ๋ผ์ด๋ฉํ๋ ๋ฉ์๋์ด๋ค.
-
๋ฐ๋ผ์ Cloneable ์ ์์ ํด๋์ค (Object) ์ ์ ์๋ clone() ์ ๋์๋ฐฉ์์ ๋ณ๊ฒฝํ๋ค๋ ์๋ฏธ์ด๋ค.
1. x.clone() != x // ๋ณต์ฌํ ๊ฐ์ฒด๋ ์๋ณธ ๊ฐ์ฒด์ ๋
๋ฆฝ์ ์.
2. x.clone().getClass() == x.getClass(); // ๋ณต์ฌํ ๊ฐ์ฒด์ ์๋ณธ ๊ฐ์ฒด๋ ๊ฐ์ ํด๋์ค์.
3. x.clone().equals(x)
๊ด๋ก์, clone() ์ super.clone() ์ ํตํด ๊ฐ์ฒด๋ฅผ ์ป์ด์ ๋ฐํํ๋ค.
์ ์กฐ๊ฑด์ ํ์๊ฐ ์๋์ ํ
- ์์ฑ์ ์ฐ์
-
์ด๋ค ํด๋์ค์์ clone() ์ new ํค์๋๋ฅผ ํตํด ๋ณต์ฌํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ ์ํ๋ค๊ณ ์๊ฐํด๋ณด์.
-
์ด ์ฌ์ ์๋ ์ปดํ์ผ์์ ๋ฌธ์ ๊ฐ ์๋ค.
-
ํ์ง๋ง ๊ทธ ํด๋์ค๋ฅผ ์์ํ ํด๋์ค์์ super.clone() ์ ํ๋ค๋ฉด, ํ์ ํด๋์ค์ ํ์ ์ด ์๋ ์์ ํด๋์ค์ ํ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
-
ํด๋์ค๊ฐ final ์ด๋ฉด ํ์ ํด๋์ค๊ฐ ์์ผ๋ new ๋ฅผ ์จ๋ ๊ด์ฐฎ๋ค. (ํ์ง๋ง Cloneable ๊ตฌํ์ด์ ๋ ์๋ค)
ํด๋์ค์ ํ๋๊ฐ ๋ชจ๋ ๋ถ๋ณ์ด๋ฉด ์๋์ฒ๋ผ ํ๋ฉด ๋๋ค.
- super.clone() ํธ์ถ
- ํด๋ผ์ด์ธํธ๊ฐ ํ๋ณํ์ ํ ํ์์๊ฒ ๊ณต๋ณ ๋ณํ ํ์ดํ์ ์ ์ฉ
- ๊ฒฐ๊ณผ ๋ฐํ
๊ฐ๋ณ ํ๋๋ฅผ super.clone() ์ผ๋ก ๋ณต์ ํด๋ฒ๋ฆฌ๋ฉด,
๊ฐ์ ๋ณต์ ํ๋ ๊ฒ์ด ์๋๋ผ ์ฃผ์๊ฐ์ ๋ณต์ฌํ์ฌ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์๋ค.
clone ์ ์๋ณธ ๊ฐ์ฒด์ ์๋ฌด๋ฐ ์ํฅ์ ๋ผ์น์ง ์๋ ๋์์ ๋ณต์ ๋ ๊ฐ์ฒด์ ๋ถ๋ณ์์ ๋ณด์ฅํด์ผ ํ๋ค.
clone() ์์ ์ฌ๊ท์ ์ผ๋ก ๊ฐ๋ณ ๊ฐ์ฒด ์ฐธ์กฐ ํ๋๋ฅผ ๋ณต์ฌํ๋ฉด ๋๋ค.
๊ทธ๋ฐ๋ฐ ๋ง์ฝ ๊ฐ๋ณ ์ฐธ์กฐ ํ๋๊ฐ final ์ด๋ผ๋ฉด ์๋ก์ด ๊ฐ์ ์ฐธ์กฐํ ์ ์์ผ๋ฏ๋ก ์์ ๋ฐฉ์์ ์ ์ฉํ ์ ์๋ค.
๊ฐ๋ณ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ํ๋๋ final ๋ก ์ ์ธํ๋ผ ๋ผ๋ ์ฉ๋ฒ๊ณผ ์ถฉ๋ํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ Cloneable ์ ๊ตฌํํ๋ฉด final ์ ๋๋ฒ๋ ค์ผ ํ๋ ์ํฉ์ด ์ฌ ์ ์๋ค.
๋ง์ฝ ๋ฐฐ์ด ์์ ๊ฐ๋ณ ์ฐธ์กฐ ๊ฐ์ฒด๊ฐ ์๋ค๋ฉด?
์ฌ๊ท์ ์ธ clone() ํธ์ถ์ผ๋ก๋ ๋ถ์กฑํ๋ค.
๊ทธ๋ด๋๋ Deep copy ๋ฅผ ํ๋ค.
public Entry deepCopy() {
return new Entry(key, value, next == null ? null : next.deepCopy());
}
@Override
public CustomHashTable clone() {
try {
CustomHashTable result = (CustomHashTable) super.clone();
result.buckets = new Entry[buckets.length];
for (int i = 0; i < buckets.length; i++) {
if (buckets[i] != null)
result.buckets[i] = buckets[i].deepCopy();
}
return result;
} catch (final CloneNotSupportedException e) {
throw new AssertionError();
}
}
์ด ๋ฐฉ์์ ์์ ์๋งํผ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ๋ง๋ ๋ค.
๋ฐ๋ผ์ ์์ ์๋งํผ์ ์คํ ํ๋ ์์ ์๋นํ๊ณ , ์คํ ์ค๋ฒํ๋ก๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
๊ทธ๋ด๋ ๋ฐ๋ณต์๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํํ ์ ์๋ค.
public Entry deepCopy() {
Entry result = new Entry(key, value, next);
for (Entry p = result; p.next != null; p = p.next) {
p.next = new Entry(p.next.key, p.next.value, p.next.next);
}
return result;
}
- Collection ์ put, add ๊ฐ์ API ๋ฅผ ์ด์ฉํ์ฌ ์์๋ฅผ ๋ณต์
- ์๋์ ์ผ๋ก ๋๋ฆฌ๋ค.
- ํ์ ํด๋์ค์์ ์ฌ์ ์ํ ๋ฉ์๋๋ฅผ ์ธ ์ ์๊ฒ ๋๋ค.
- public ์ด์ด์ผ ์ฌ์ฉํ๊ธฐ๊ฐ ์ฝ๋ค.
- throw ๋ฅผ ๋์ง๋ ๊ฒ์ ๊ณ์ ์ ์ํ๋ฉด ํ์ ํด๋์ค์๋ ๊ณ์ try-catch ๋ฅผ ์จ์ค์ผ ํ๋ค.
- Cloneable ์ ๊ตฌํํ๋ฉด, clone() ์ ์ฌ์ ์ํด์ผ ํ๋ค.
- ์ ๊ทผ์๋ public, ๋ฐํํ์ ์๊ธฐ์์ ์ ํ์ ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
- ๊ณต๋ณ ๋ณํ ํ์ดํ์ ํตํด ์๊ธฐ์์ ์ ํ์ ์ ๋ฐํํ๋ค.
- super.clone() ์ผ๋ก ๋ณต์ ํ๋ค.
- ๊น์ ๋ณต์ ๋ฐฉ์์ผ๋ก ๊ฐ๋ณ ์ฐธ์กฐ ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ๋ค.
๋ฐฐ์ด๋ง์ด clone() ์ ์ฌ๋๋ก ์ฌ์ฉํ๋ ์ ์ผํ ์์ด๋ค. ๋ณต์ฌํ๋ ๋์์ด ๋ฐฐ์ด์ด ์๋๋ฉด ๋ณต์ฌ ์์ฑ์, ๋ณต์ฌ ํฉํฐ๋ฆฌ๊ฐ ์ข๋ค.
๋ณต์ฌ ์์ฑ์
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack(Stack s) {
this.elements = s.elements.clone();
this.size = s.size;
}
}
๊ธฐ๋ณธ ์์ฑ์๊ฐ ํ์ํ๋ฉด ์ถ๊ฐํ๊ธฐ
๋ณต์ฌ ํฉํฐ๋ฆฌ
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public static Stack newInstance(Stack s) {
return new Stack(s.elements, s.size);
}
}