item 13 dodo4513 - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
- Cloneable์ ๋ณต์ ํด๋ ๋๋ ํด๋์ค์์ ๋ช ์ํ๋ ์ฉ๋์ ๋ฏน์ค์ธ ์ธํฐํ์ด์ค์ง๋ง, ์์ฝ๊ฒ๋ ์๋ํ ๋ชฉ์ ์ ์ ๋๋ก ์ด๋ฃจ์ง ๋ชปํ๋ค. ๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ clone ๋ฉ์๋๊ฐ ์ ์ธ๋ ๊ณณ์ด Cloneable์ด ์๋ Object์ด๊ณ , ๊ทธ๋ง์ ๋ protected๋ผ๋ ๋ฐ ์๋ค. ๊ทธ๋์ Cloneable์ ๊ตฌํํ๋ ๊ฒ๋ง์ผ๋ก๋ ์ธ๋ถ ๊ฐ์ฒด์์ clone ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ค. ๋ฆฌํ๋ ์ (์์ดํ 65)์ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฅํ์ง๋ง, 100% ์ฑ๊ณตํ๋ ๊ฒ๋ ์๋๋ค. ํด๋น ๊ฐ์ฒด๊ฐ ์ ๊ทผ์ด ํ์ฉ๋ clone ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค๋ ๋ณด์ฅ์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
-
์์ ๊ฐ์ ๋ฌธ์ ์ ์๋ ๋ถ๊ตฌํ๊ณ Cloneable ๋ฐฉ์์ ๋๋ฆฌ ์ฐ์ด๊ณ ์์ด์ ์ ์์๋๋ ๊ฒ์ด ์ข๋ค. ์ด๋ฒ ์์ดํ ์์๋ clone ๋ฉ์๋๋ฅผ ์ ๋์ํ๊ฒ๋ ํด์ฃผ๋ ๊ตฌํ ๋ฐฉ๋ฒ๊ณผ ์ธ์ ๊ทธ๋ ๊ฒ ํด์ผ ํ๋์ง๋ฅผ ์๋ ค์ฃผ๊ณ , ๊ฐ๋ฅํ ๋ค๋ฅธ ์ ํ์ง์ ๊ดํด ๋ ผ์ํ๊ฒ ๋ค.
-
๋ช ์ธ์์๋ ์ด์ผ๊ธฐํ์ง ์์ง๋ง ์ค๋ฌด์์ Cloneable์ ๊ตฌํํ ํด๋์ค๋ clone ๋ฉ์๋๋ฅผ public์ผ๋ก ์ ๊ณตํ๋ฉฐ, ์ฌ์ฉ์๋ ๋น์ฐํ ๋ณต์ ๊ฐ ์ ๋๋ก ์ด๋ค์ง๋ฆฌ๋ผ ๊ธฐ๋ํ๋ค. ๊ทธ๋ฌ๋...
์ด ๊ฐ์ฒด์ ๋ณต์ฌ๋ณธ์ ์์ฑํด ๋ฐํํ๋ค.
โ๋ณต์ฌโ์ ์ ํํ ๋ป์ ๊ทธ ๊ฐ์ฒด๋ฅผ ๊ตฌํํ ํด๋์ค์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์๋ค.
์ผ๋ฐ์ ์ธ ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ด๋ค ๊ฐ์ฒด x์ ๋ํด ๋ค์ ์์ ์ฐธ์ด๋ค.
x.clone() != x
๋ํ ๋ค์ ์๋ ์ฐธ์ด๋ค.
x.clone().getClass() == x.getClass()
ํ์ง๋ง ์ด์์ ์๊ตฌ๋ฅผ ๋ฐ๋์ ๋ง์กฑํด์ผ ํ๋ ๊ฒ์ ์๋๋ค.
ํํธ ๋ค์ ์๋ ์ผ๋ฐ์ ์ผ๋ก ์ฐธ์ด์ง๋ง, ์ญ์ ํ์๋ ์๋๋ค.
x.clone().equals(x)
๊ด๋ก์, ์ด ๋ฉ์๋๊ฐ ๋ฐํํ๋ ๊ฐ์ฒด๋ super.clone์ ํธ์ถํด ์ป์ด์ผ ํ๋ค.
์ด ํด๋์ค์ (Object๋ฅผ ์ ์ธํ) ๋ชจ๋ ์์ ํด๋์ค๊ฐ ์ด ๊ด๋ก๋ฅผ ๋ฐ๋ฅธ๋ค๋ฉด ๋ค์ ์์ ์ฐธ์ด๋ค.
x.clone().getClass() == x.getClass()
๊ด๋ก์, ๋ฐํ๋ ๊ฐ์ฒด์ ์๋ณธ ๊ฐ์ฒด๋ ๋ ๋ฆฝ์ ์ด์ด์ผ ํ๋ค.
์ด๋ฅผ ๋ง์กฑํ๋ ค๋ฉด super.clone์ผ๋ก ์ป์ ๊ฐ์ฒด์ ํ๋ ์ค ํ๋ ์ด์์ ๋ฐํ ์ ์ ์์ ํด์ผ ํ ์๋ ์๋ค.
- ๊ฐ์ ์ฑ์ด ์๋ค๋ ์ ๋ง ๋นผ๋ฉด ์์ฑ์ ์ฐ์(constructor chaining)์ ์ด์ง ๋น์ทํ ๋ฉ์ปค๋์ฆ์ด๋ค. ์ฆ, clone ๋ฉ์๋๊ฐ super.clone์ด ์๋, ์์ฑ์๋ฅผ ํธ์ถํด ์ป์ ์ธ์คํด์ค๋ฅผ ๋ฐํํด๋ ์ปดํ์ผ๋ฌ๋ ๋ถํํ์ง ์์ ๊ฒ์ด๋ค.
- ํ์ง๋ง ์ด ํด๋์ค์ ํ์ ํด๋์ค์์ super.clone์ ํธ์ถํ๋ค๋ฉด ์๋ชป๋ ํด๋์ค์ ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ ธ, ๊ฒฐ๊ตญ ํ์ ํด๋์ค์ clone ๋ฉ์๋๊ฐ ์ ๋๋ก ๋์ํ์ง ์๊ฒ ๋๋ค.
@Override public PhoneNumber clone() {
try {
return (PhoneNumber) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(); // ์ผ์ด๋ ์ ์๋ ์ผ์ด๋ค.
}
}
- ๊ฐ๋ณ ์ํ๋ฅผ ์ฐธ์กฐํ์ง ์๋ ํด๋์ค์ฉ clone ๋ฉ์๋๋ ์์ ๊ฐ์ด ์ฌํํ๋ค.
class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
Object result = elements[--size];
elements[size] = null; // ๋ค ์ด ์ฐธ์กฐ ํด์
return result;
}
// ๊ฐ๋ณ ์ํ๋ฅผ ์ฐธ์กฐํ์ง ์๋ ํด๋์ค์ฉ clone ๋ฉ์๋
@Override
public Stack clone() {
try {
return (Stack) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
- ์ด ํด๋์ค๋ฅผ ๋ณต์ ํ ์ ์๋๋ก ๋ง๋ค์ด๋ณด์.
- clone ๋ฉ์๋๊ฐ ๋จ์ํ super.clone์ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋๋ก ๋ฐํํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น? ๋ฐํ๋ Stack ์ธ์คํด์ค์ size ํ๋๋ ์ฌ๋ฐ๋ฅธ ๊ฐ์ ๊ฐ๊ฒ ์ง๋ง, elements ํ๋๋ ์๋ณธ Stack ์ธ์คํด์ค์ ๋๊ฐ์ ๋ฐฐ์ด์ ์ฐธ์กฐํ ๊ฒ์ด๋ค.
- ์๋ณธ์ด๋ ๋ณต์ ๋ณธ ์ค ํ๋๋ฅผ ์์ ํ๋ฉด ๋ค๋ฅธ ํ๋๋ ์์ ๋์ด ๋ถ๋ณ์์ ํด์น๋ค๋ ์ด์ผ๊ธฐ๋ค. ๋ฐ๋ผ์ ํ๋ก๊ทธ๋จ์ด ์ด์ํ๊ฒ ๋์ํ๊ฑฐ๋ NullPointerException์ ๋์ง ๊ฒ์ด๋ค.
// ๊ฐ๋ณ ์ํ๋ฅผ ์ฐธ์กฐํ๋ ํด๋์ค์ฉ clone ๋ฉ์๋
@Override
public Stack clone() {
try {
Stack result = (Stack) super.clone();
result.elements = elements.clone();
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
- Stack ํด๋์ค์ ํ๋๋ฟ์ธ ์์ฑ์๋ฅผ ํธ์ถํ๋ค๋ฉด ์ด๋ฌํ ์ํฉ์ ์ ๋ ์ผ์ด๋์ง ์๋๋ค.
clone ๋ฉ์๋๋ ์ฌ์ค์ ์์ฑ์์ ๊ฐ์ ํจ๊ณผ๋ฅผ ๋ธ๋ค.
์ฆ, clone์ ์๋ณธ ๊ฐ์ฒด์ ์๋ฌด๋ฐ ํด๋ฅผ ๋ผ์น์ง ์๋ ๋์์ ๋ณต์ ๋ ๊ฐ์ฒด์ ๋ถ๋ณ์์ ๋ณด์ฅํด์ผ ํ๋ค.
๊ทธ๋์ Stack์ clone ๋ฉ์๋๋ ์ ๋๋ก ๋์ํ๋ ค๋ฉด ์คํ ๋ด๋ถ ์ ๋ณด๋ฅผ ๋ณต์ฌํด์ผ ํ๋๋ฐ, ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ elements ๋ฐฐ์ด์ clone์ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํด ์ฃผ๋ ๊ฒ์ด๋ค.
// ๋ณต์ฌ ์์ฑ์
public Yum(Yum yum) { ... };
// ๋ณต์ฌ ํฉํฐ๋ฆฌ
public static Yum newInstance(Yum yum) { ... };
- ๋คํํ๋ ์ด์ฒ๋ผ ๋ณต์กํ ๊ฒฝ์ฐ๋ ๋๋ฌผ๋ค. Cloneable์ ์ด๋ฏธ ๊ตฌํํ ํด๋์ค๋ฅผ ํ์ฅํ๋ค๋ฉด ์ด์ฉ ์ ์์ด clone์ ์ ์๋ํ๋๋ก ๊ตฌํํด์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ ์ํฉ์์๋ ๋ณต์ฌ ์์ฑ์์ ๋ณต์ฌ ํฉํฐ๋ฆฌ๋ผ๋ ๋ ๋์ ๊ฐ์ฒด ๋ณต์ฌ ๋ฐฉ์์ ์ ๊ณตํ ์ ์๋ค.
Cloneable์ด ๋ชฐ๊ณ ์จ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ๋์ง์ด๋ดค์ ๋, ์๋ก์ด ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค ๋๋ ์ ๋ Cloneable์ ํ์ฅํด์๋ ์ ๋๋ฉฐ, ์๋ก์ด ํด๋์ค๋ ์ด๋ฅผ ๊ตฌํํด์๋ ์ ๋๋ค. final ํด๋์ค๋ผ๋ฉด Cloneable์ ๊ตฌํํด๋ ์ํ์ด ํฌ์ง ์์ง๋ง, ์ฑ๋ฅ ์ต์ ํ ๊ด์ ์์ ๊ฒํ ํ ํ ๋ณ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ์์ ๋๋ง ๋๋ฌผ๊ฒ ํ์ฉํด์ผ ํ๋ค. ๊ธฐ๋ณธ ์์น์
๋ณต์ ๊ธฐ๋ฅ์ ์์ฑ์์ ํฉํฐ๋ฆฌ๋ฅผ ์ด์ฉํ๋ ๊ฒ ์ต๊ณ
๋ผ๋ ๊ฒ์ด๋ค. ๋จ, ๋ฐฐ์ด๋ง์ clone ๋ฉ์๋ ๋ฐฉ์์ด ๊ฐ์ฅ ๊น๋ํ, ์ด ๊ท์น์ ํฉ๋นํ ์์ธ๋ผ ํ ์ ์๋ค.