description |
---|
μ΄λ² μμ΄ν
μ clone()μ μ¬μ©ν λ μ£Όμμ μ λ€λ£¬λ€. |
- μΌμ’
μ
maker interface
λ‘ 'cloenμ μν΄ λ³΅μ ν μ μλ€'λ₯Ό νμνλ μΈν°νμ΄μ€μ΄λ€. - 볡μ ν΄λ λλ ν΄λμ€μμ λͺ μνλ μ©λμ λ―Ήμ€μΈ μΈν°νμ΄μ€
Javaμμλ μΈμ€ν΄μ€μ 볡μ λ₯Ό μν΄ clone()
λ©μλκ° κ΅¬νλμ΄ μλ€.
μ κΈ°νκ²λ μ΄ λ©μλλ Cloneable
λ΄λΆμ ꡬνλμ΄ μμ κ±°λ μμμ κΉ¨κ³ java.lang.Object
ν΄λμ€μ protected μ κ·Ό μ§μ μλ‘ κ΅¬νλμ΄ μλ€. λ΄λΆμλ ꡬνν΄μΌ ν λ©μλκ° νλλ μλ€!
- Objectμ protected λ©μλμΈ cloneμ λμ λ°©μμ κ²°μ νλ€.
- Cloneableμ κ²½μ°, μΌλ°μ μΌλ‘ μΈν°νμ΄μ€λ₯Ό ꡬννλ€λ κ² μ¦, ν΄λΉ ν΄λμ€κ° κ·Έ μΈν°νμ΄μ€μμ μ μν κΈ°λ₯μ μ 곡νλ€κ³ μ μΈνλ κ²κ³Ό λ¬λ¦¬ μμ ν΄λμ€μ μ μλ protected λ©μλμ λμλ°©μμ λ³κ²½ν κ²
public class Pokemon implements Cloneable {
private List<String> skills;
private int attack;
private int defense;
private int hp;
public Pokemon(List<String> skills, int attack, int defense, int hp) {
this.skills = skills;
this.attack = attack;
this.defense = defense;
this.hp = hp;
}
@Override // clone() ꡬν..!!
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// getter, seterr ...
}
볡μ¬ν κ°μ²΄μ Cloneable
μ μμμμΌ μ€ λ€ μ€λ²λΌμ΄λ©ν΄ μ£Όλ©΄ λλ€.
clone()
μ νΈμΆνλ©΄ μΈμ€ν΄μ€μ κ°μ ν¬κΈ°μ λ©λͺ¨λ¦¬λ₯Ό ν λΉνκ³ , μΈμ€ν΄μ€μ νλλ₯Ό κ·Έλλ‘ λ³΅μ¬ν 볡μ¬λ³Έμ 리ν΄νλ€.
- 볡μ‘μ±κ³Ό μνμ±
Cloneable
κ³Όclone()
λ©μλλ κ°μ²΄ λ³΅μ¬ λ©μ»€λμ¦μ΄ μ§κ΄μ μ΄μ§ μκ³ , μλͺ» ꡬννλ©΄ μ€λ₯κ° λ°μνκΈ° μ½λ€.- κ°λ³ κ°μ²΄μ 볡μ¬,
final
νλμμ μΆ©λ, μμΈ μ²λ¦¬ λ± μ¬λ¬ κ°μ§ λ¬Έμ κ° μλ€.
π€ Cloneableμ ꡬνν ν΄λμ€λ clone λ©μλλ₯Ό publicμΌλ‘ μ 곡νλ©°, μ¬μ©μλ λΉμ°ν 볡μ κ° μ λλ‘ μ΄λ€μ§κ² μ§? λΌκ³ μ€λ¬΄μμλ κΈ°λ
μ΄ κΈ°λλ₯Ό λ§μ‘±μν€λ €λ©΄ κ·Έ ν΄λμ€μ λͺ¨λ μμ ν΄λμ€λ λ³΅μ‘ νκ³ , κ°μ ν μ μκ³ , νμ νκ² κΈ°μ λ νλ‘ν μ½μ μ§μΌμΌλ§ νλλ°, κ·Έ κ²°κ³Ό λ‘ κΉ¨μ§κΈ° μ½κ³ , μννκ³ , λͺ¨μμ μΈ λ©μ»€λμ¦μ΄ νμνλ€. μμ±μλ₯Ό νΈμΆνμ§ μκ³ λ κ°μ²΄λ₯Ό μμ±ν μ μκ² λλ κ²μ΄λ€.
μ½κ° νμ νλ€κ³ ν¨
- x.clone() ! =x μμ μ°Έμ΄μ΄μΌ νλ€.
- 볡μ¬λ κ°μ²΄μ μλ³Έμ΄λ κ°μ μ£Όμλ₯Ό κ°μ§λ©΄ μλλ€λ λ»
- x.clone().getClass() == x.getClass() μλ μ°Έμ΄μ΄μΌ νλ€.
- 볡μ¬λ κ°μ²΄κ° κ°μ ν΄λμ€μ¬μΌ νλ€λ μ리μ
- x.clone().equals(x) μ°Έμ΄μ΄μΌ νμ§λ§ νμλ μλλ€.
- 볡μ¬λ κ°μ²΄κ° λ Όλ¦¬μ λμΉλ μΌμΉν΄μΌ νλ€κ³ ν¨
λ°νλ κ°μ²΄μ μλ³Έ κ°μ²΄λ λ 립μ μ΄μ΄μΌ νλ€. μ΄λ₯Ό λ§μ‘±νλ €λ©΄ super.cloneμΌλ‘ μ»μ κ°μ²΄μ νλ μ€ νλ μ΄μμ λ°ν μ μ μμ ν΄μΌ ν μλ μλ€.
super.clone()
μ νΈμΆν΄μΌ νλ μ΄μ
clone()
λ©μλλ₯Ό μ¬μ μν λ κ°μ₯ λ¨Όμ ν΄μΌ ν μΌμ super.clone()
μ νΈμΆνλ κ²μ΄λ€. μ΄λ Object
ν΄λμ€μ clone()
λ©μλλ₯Ό ν΅ν΄ κ°μ²΄μ νλ κ°μ 볡μ¬ν μλ‘μ΄ κ°μ²΄λ₯Ό μμ±νκΈ° μν¨μ΄λ€.
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
νμ ν΄λμ€μμμ λ¬Έμ μ
λ§μ½ super.clone()
μ νΈμΆνμ§ μκ³ μμ±μλ₯Ό μ¬μ©νμ¬ μΈμ€ν΄μ€λ₯Ό λ°ννλ€λ©΄, νμ ν΄λμ€μμ super.clone()
μ νΈμΆν λ μ¬λ°λ₯Έ ν΄λμ€μ κ°μ²΄κ° μμ±λμ§ μμ μ μλ€. μ΄λ νμ ν΄λμ€μ clone()
λ©μλκ° μ λλ‘ λμνμ§ μκ² λ§λ€ μ μλ€.
- μμ: μμ ν΄λμ€μμ
super.clone()
μ νΈμΆνμ§ μκ³ μλ‘μ΄ κ°μ²΄λ₯Ό μμ±νλ©΄, νμ ν΄λμ€μμsuper.clone()
μ νΈμΆν΄λ μμ ν΄λμ€μ μΈμ€ν΄μ€κ° λ°νλμ΄ νμ ν΄λμ€μ νλκ° μ΄κΈ°νλμ§ μμ μ μλ€.
final
ν΄λμ€μ κ²½μ°
ν΄λμ€κ° final
μ΄λΌλ©΄ νμ ν΄λμ€κ° μμΌλ―λ‘ μ΄ κ·μΉμ 무μν΄λ μμ νλ€. κ·Έλ¬λ μ΄ κ²½μ°μλ Cloneable
μ ꡬνν νμκ° μλ€. Object
μ clone()
λ©μλλ₯Ό μ¬μ©νμ§ μκΈ° λλ¬Έμ΄λ€.
super.clone()
μ νΈμΆνλ€.
- μ μλ λͺ¨λ νλλ μλ³Έ νλμ λκ°μ κ°μ κ°κ² λλ€.
- λͺ¨λ νλκ° primitive νμ μ΄κ±°λ final μ΄λΌλ©΄, μ΄ μνλ‘ λμ΄λ€.
- μ¬μ€ finalμ μΈλ° μλ 볡μ¬λ₯Ό μ§μνκΈ° λλ¬Έμ clone()μ΄ νμ μλ€.
@Override
public PhoneNumber clone() {
try {
return (PhoneNumber) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(); // μΌμ΄λ μ μλ μΌμ΄λ€.
}
}
- PhoneNumber νμ μΌλ‘ νλ³ννμ¬ λ°ννλλ‘ ν΄μ νΈμμ±μ μ¦λμμΌ°λ€.
- try-catch λΈλ‘μΌλ‘ κ°μΌ μ΄μ λ Object.clone() λ©μλκ°
CloneNotSupportedException
μ λμ§κΈ° λλ¬Έμ΄λ€.
μ°λ¦° PhoneNumber ν΄λμ€κ° Cloneable μΈν°νμ΄μ€λ₯Ό μμλ°λ κ²μ λ³΄κ³ clone()μ μ§μν¨μ μ μ μλ€.
CloneNotSupportedException μμΈ μ²λ¦¬
Object
μclone()
λ©μλλCloneNotSupportedException
μ λ€.Cloneable
μ ꡬνν ν΄λμ€μμclone()
λ©μλλ₯Ό μ¬μ μν λλ μ΄ μμΈλ₯Ό λμ§ νμκ° μμ΅λλ€.- λμ
try-catch
λΈλ‘μΌλ‘ κ°μΈκ³ , μμΈκ° λ°μν μ μμμ 보μ₯νκΈ° μν΄AssertionError
1λ₯Ό λμ§λ€. - κ³Όλν κ²μ¬ μμΈλ APIλ₯Ό μ¬μ©νκΈ° λΆνΈνκ² λ§λ λ€.
{% hint style="info" %} κ°λ³κ°μ²΄λ, instance μμ± μ΄νμλ λ΄λΆ μν λ³κ²½μ΄ κ°λ₯ν κ°μ²΄λ₯Ό λ§νλ€. {% endhint %}
- μ΄ ν΄λμ€λ₯Ό κ·Έλλ‘ λ³΅μ νλ©΄, primitive νμ μ κ°μ μ¬λ°λ₯΄κ² 볡μ λμ§λ§, 볡μ λ Stackμ elementsλ 볡μ μ μ Stackκ³Ό κ°μ λ°°μ΄μ κ°λ¦¬ν€κ² λ κ²μ΄λ€.
- λ μ€νμ κ°μ elementsκ° λ€μ΄μκ³ , νλλ₯Ό λ°κΎΈλ©΄ λ€λ₯Έ νλλ μ°λλλ€λ λ»μ΄λ€. μ΄κ±΄ μ°λ¦¬κ° μν clone()μ΄ μλλ€.
- μλ₯Ό λ€μ΄,
Stack
ν΄λμ€μelements
λ°°μ΄μ΄ μ΄μ ν΄λΉνλ€. Stack
ν΄λμ€μ μ μΌν μμ±μλ₯Ό μ΄μ©νλ©΄ μ΄λ° λ¬Έμ λ μμ κ²μ΄λ€. κ·Έλ¬λ κ°μ΄ 볡μ¬λμ§ μλ λ¬Έμ κ° μλ€.
μμ 볡μ¬μ λ¬Έμ μ
- λ¨μν
super.clone()
μ νΈμΆνλ©΄ μμ 볡μ¬κ° μ΄λ£¨μ΄μ Έ, κ°μ²΄μ νλ κ°λ§ 볡μ¬λκ³ κ·Έ νλλ€μ΄ μ°Έμ‘°νλ κ°μ²΄λ€μ 볡μ¬λμ§ μλλ€. - λ°λΌμ κ°λ³ κ°μ²΄λ₯Ό μ°Έμ‘°νλ νλκ° μμ κ²½μ°, μλ³Έ κ°μ²΄μ 볡μ λ κ°μ²΄κ° λμΌν κ°λ³ κ°μ²΄λ₯Ό 곡μ νκ² λλ€.
- λ¬Έμ μ : μλ³Έμ΄λ 볡μ λ³Έ μ€ νλμμ κ°λ³ κ°μ²΄λ₯Ό λ³κ²½νλ©΄ λ€λ₯Έ νλμλ μν₯μ λ―Έμ³ λΆλ³μμ΄ κΉ¨μ§ μ μλ€.
κΉμ 볡μ¬μ νμμ±
μλ³Έκ³Ό 볡μ λ³Έμ΄ λ 립μ μΈ κ°μ²΄ μνλ₯Ό μ μ§νλ €λ©΄ κ°λ³ κ°μ²΄λ₯Ό 볡μ¬ν΄μΌ νλ€. μ΄λ₯Ό μν΄ ν΄λΉ νλλ₯Ό κΉμ 볡μ¬νμ¬ μλ‘μ΄ κ°μ²΄λ₯Ό μμ±ν΄μΌ νλ€.
λ°°μ΄μ clone()
λ©μλ μ¬μ©
λ°°μ΄μ clone()
λ©μλλ₯Ό νΈμΆνλ©΄ κΉμ 볡μ¬κ° μ΄λ£¨μ΄μ§λλ€. μ¦, λ°°μ΄ μμ²΄κ° λ³΅μ¬λκ³ λ°°μ΄μ κ° μμλ€λ 볡μ¬λ©λλ€. λ°λΌμ λ°°μ΄μ 볡μ ν λλ λ°°μ΄μ clone()
λ©μλλ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
- μμ:
@Override
public Stack clone() {
try {
// λ¨Όμ super.clone()μ νΈμΆνμ¬ μ΄ κ°μ²΄μ μμ 볡μ¬(shallow copy)λ₯Ό μνν©λλ€.
Stack result = (Stack) super.clone();
// elements λ°°μ΄μ 볡μ νμ¬ μλ³Έκ³Ό 볡μ λ³Έμ΄ μλ‘ λ€λ₯Έ λ°°μ΄μ μ°Έμ‘°νλλ‘ ν©λλ€.
result.elements = elements.clone();
// 볡μ λ Stack κ°μ²΄λ₯Ό λ°νν©λλ€.
return result;
} catch (CloneNotSupportedException e) {
// μ΄ μμΈλ λ°μνμ§ μμΌλ―λ‘ AssertionErrorλ₯Ό λμ§λλ€.
// Cloneableμ ꡬννκΈ° λλ¬Έμ super.clone()μ μ±κ³΅ν΄μΌ ν©λλ€.
throw new AssertionError();
}
}
π§ μ elements
λ°°μ΄μ 볡μ νλμ?
elements
λ°°μ΄μStack
μ λ΄λΆ μνλ₯Ό μ μ₯νλ μ€μν κ°λ³ κ°μ²΄μ΄λ€.- μλ³Έκ³Ό 볡μ λ³Έμ΄ κ°μ λ°°μ΄μ 곡μ νλ©΄ νμͺ½μμ λ³κ²½μ΄ λ°μν λ λ€λ₯Έ μͺ½μλ μν₯μ λ―ΈμΉλ€.
- μ΄λ₯Ό λ°©μ§νκΈ° μν΄
elements
λ°°μ΄μ 볡μ νμ¬ λ³΅μ λ³Έμ΄ λ 립μ μΈ λ°°μ΄μ κ°μ§λλ‘ νλ€.
μ¬μ©μμ
public class Stack implements Cloneable {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
// μμ±μ
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
// push λ©μλ
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
// pop λ©μλ
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // λ€ μ΄ μ°Έμ‘° ν΄μ
return result;
}
// λ΄λΆ λ°°μ΄μ ν¬κΈ° μ‘°μ
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
// clone λ©μλ
@Override
public Stack clone() {
try {
Stack result = (Stack) super.clone();
result.elements = elements.clone(); // λ°°μ΄ λ³΅μ
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
public class Main {
public static void main(String[] args) {
Stack originalStack = new Stack();
originalStack.push("A");
originalStack.push("B");
// μ€ν 볡μ
Stack clonedStack = originalStack.clone();
// μλ³Έ μ€νκ³Ό 볡μ λ³Έ μ€νμ΄ λ³κ°μ κ°μ²΄μΈμ§ νμΈ
System.out.println(originalStack != clonedStack); // true
// elements λ°°μ΄μ΄ λ³κ°μ κ°μ²΄μΈμ§ νμΈ
System.out.println(originalStack.elements != clonedStack.elements); // true
// μλ³Έκ³Ό 볡μ λ³Έμ λ΄μ©μ΄ κ°μμ§ νμΈ
System.out.println(Arrays.equals(originalStack.elements, clonedStack.elements)); // true
// μλ³Έ μ€νμ μΆκ°
originalStack.push("C");
// 볡μ λ³Έμλ μν₯μ΄ μλμ§ νμΈ
System.out.println(clonedStack.size); // 2
}
}
- μ€λͺ
:
originalStack
μ μμ±νκ³ "A", "B"λ₯Ό μΆκ°originalStack
μ 볡μ νμ¬clonedStack
μ μμ±- μλ³Έκ³Ό 볡μ λ³Έμ΄ μλ‘ λ€λ₯Έ κ°μ²΄μ΄κ³ , λ΄λΆμ
elements
λ°°μ΄λ λ€λ₯Έ κ°μ²΄μμ νμΈ - μλ³Έ μ€νμ "C"λ₯Ό μΆκ°ν΄λ 볡μ λ³Έμλ μν₯μ΄ μλ€.
ν μ€νΈ κ²°κ³Ό:
stack1 = [value1, value2, null, null, null, null, null, null, null, null, null, null, null, null, null, null]
stack2 = [value1, value2, value3, null, null, null, null, null, null, null, null, null, null, null, null, null]
stack1
κ³Όstack2
λ μλ‘ λ€λ₯Έelements
λ°°μ΄μ κ°μ§κ³ μμΌλ©°, λ 립μ μΌλ‘ λμνλ€.
μμ½
clone()
λ©μλλ₯Ό μ¬μ μν λλsuper.clone()
μ νΈμΆνμ¬ κ°μ²΄μ μμ 볡μ¬λ₯Ό μννλ€.- κ°λ³ κ°μ²΄λ₯Ό μ°Έμ‘°νλ νλλ λ°λμ 볡μ νμ¬ μλ³Έκ³Ό 볡μ λ³Έμ΄ λ 립μ μΈ κ°μ²΄ μνλ₯Ό μ μ§νλλ‘ νλ€.
CloneNotSupportedException
μ λ°μνμ§ μμ§λ§ μμΈ μ²λ¦¬λ₯Ό μν΄try-catch
λΈλ‘μ μ¬μ©νκ³ , μμΈκ° λ°μνλ©΄AssertionError
λ₯Ό λμ§λ€.Cloneable
μΈν°νμ΄μ€λ₯Ό ꡬνν΄μΌsuper.clone()
μ νΈμΆν μ μλ€.
{% hint style="info" %} π μμ λ΄μ©μ μμ½νμλ©΄ {% endhint %}
clone()
λ©μλλ₯Ό μ¬μ μν λλsuper.clone()
μ νΈμΆνμ¬ κ°μ²΄μ μμ 볡μ¬λ₯Ό μννλ€.- κ°λ³ κ°μ²΄λ₯Ό μ°Έμ‘°νλ νλλ λ°λμ 볡μ νμ¬ μλ³Έκ³Ό 볡μ λ³Έμ΄ λ 립μ μΈ κ°μ²΄ μνλ₯Ό μ μ§νλλ‘ νλ€.
CloneNotSupportedException
μ λ°μνμ§ μμ§λ§ μμΈ μ²λ¦¬λ₯Ό μν΄try-catch
λΈλ‘μ μ¬μ©νκ³ , μμΈκ° λ°μνλ©΄AssertionError
λ₯Ό λμ§λ€.Cloneable
μΈν°νμ΄μ€λ₯Ό ꡬνν΄μΌsuper.clone()
μ νΈμΆν μ μλ€.
μ°κ²° 리μ€νΈμ 볡μ λ°©λ²
μ°κ²° 리μ€νΈλ₯Ό 볡μ ν λλ κ° λ Έλλ₯Ό κ°λ³μ μΌλ‘ 볡μ¬ν΄μΌ ν©λλ€.
μ¬κ·μ 볡μ μ λ¬Έμ μ
μ¬κ·μ μΌλ‘ μ°κ²° 리μ€νΈλ₯Ό 볡μ νλ©΄ 리μ€νΈμ κΈΈμ΄λ§νΌ μ€ν νλ μμ μ¬μ©νλ―λ‘, 리μ€νΈκ° κΈΈλ©΄ μ€ν μ€λ²νλ‘μ°κ° λ°μν μ μλ€.
- μ¬κ·μ 볡μ μ½λ μμ:
public class Entry {
Object key;
Object value;
Entry next;
Entry deepCopy() {
return new Entry(key, value, next == null ? null : next.deepCopy());
}
}
λ°λ³΅λ¬Έμ μ¬μ©ν 볡μ
λ°λ³΅λ¬Έμ μ¬μ©νλ©΄ μ€ν μ€λ²νλ‘μ°μ μν μμ΄ μ°κ²° 리μ€νΈλ₯Ό 볡μ ν μ μλ€.
- λ°λ³΅λ¬Έμ μ¬μ©ν 볡μ μ½λ μμ:
public class Entry {
Object key;
Object value;
Entry next;
Entry deepCopy() {
Entry result = new Entry(key, value, null);
Entry p = result;
Entry q = this.next;
while (q != null) {
p.next = new Entry(q.key, q.value, null);
p = p.next;
q = q.next;
}
return result;
}
}
μ½λ μμ: HashTable
ν΄λμ€μ clone()
λ©μλ
public class HashTable implements Cloneable {
private Entry[] buckets;
@Override
public HashTable clone() {
try {
HashTable result = (HashTable) 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 (CloneNotSupportedException e) {
throw new AssertionError(); // λ°μνμ§ μμ
}
}
}
- κ° λ²ν·μ μ°κ²° 리μ€νΈλ₯Ό 볡μ νμ¬ μλ³Έκ³Ό 볡μ λ³Έμ΄ λ 립μ μΈ μνλ₯Ό μ μ§ν©λλ€.
μ¬μ μλ λ©μλ νΈμΆμ λ¬Έμ μ
clone()
λ©μλμμ νμ ν΄λμ€μμ μ¬μ μλ λ©μλλ₯Ό νΈμΆνλ©΄, νμ ν΄λμ€λ 볡μ κ³Όμ μμ μμ μ μνλ₯Ό μ μ ν μ΄κΈ°νν μ μκ² λλ€. μ΄λ μλ³Έκ³Ό 볡μ λ³Έμ μνκ° λ¬λΌμ§ μ μλ€λ κ²μ μλ―Έ
ν΄κ²°μ±
clone()
λ©μλ λ΄μμ νΈμΆνλ λ©μλλ final
λλ private
μΌλ‘ μ μΈνμ¬ μ¬μ μλμ§ μλλ‘ ν΄μΌ νλ€.
- μμ:
@Override
protected Object clone() throws CloneNotSupportedException {
MyClass result = (MyClass) super.clone();
result.init(); // init() λ©μλλ final λλ privateμ΄μ΄μΌ ν¨
return result;
}
- λ§μ½
elements
νλκ°final
λ‘ μ μΈλμ΄ μλ€λ©΄,clone()
λ©μλμμ μλ‘μ΄ λ°°μ΄μ ν λΉν μ μμ΄ λ¬Έμ κ° λ°μνλ€. - μ΄λ κ°λ³ κ°μ²΄λ₯Ό μ°Έμ‘°νλ νλλ
final
λ‘ μ μΈνλΌλ μΌλ°μ μΈ κ·μΉκ³Ό μΆ©λνλ€. - μ΄λ¬ν κ²½μ°,
clone()
λ©μλλ₯Ό μ¬μ©νλ λμ λ³΅μ¬ μμ±μλ₯Ό μ¬μ©νλ κ²μ΄ λ λ°λμ§νλ€.
λ³΅μ¬ μμ±μ μ¬μ© μμ
public Stack(Stack original) {
this.elements = original.elements.clone();
this.size = original.size;
}
- μ₯μ :
clone()
λ©μλλ³΄λ€ κ΅¬νμ΄ κ°λ¨νκ³ λͺ ννλ€.- μμΈ μ²λ¦¬κ° νμ μλ€.
final
νλμμ μΆ©λμ΄ μλ€.
μ¬μ© μμ
javaμ½λ 볡μ¬Stack stack1 = new Stack();
stack1.push("value1");
stack1.push("value2");
Stack stack2 = new Stack(stack1); // λ³΅μ¬ μμ±μ μ¬μ©
stack2.push("value3");
stack1
κ³Όstack2
λ λ 립μ μΈ μ€νμΌλ‘ λμνλ€.
μλͺ»λ clone()
λ©μλ:
static class HashTable implements Cloneable {
private Entry[] buckets;
private static class Entry {
final Object key;
Object value;
Entry next;
public Entry(Object key, Object value, Entry next) {
this.key = key;
this.value = value;
this.next = next;
}
}
@Override
public HashTable clone() {
try {
HashTable result = (HashTable) super.clone();
result.buckets = buckets.clone(); // buckets λ°°μ΄λ§ 볡μ
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
buckets
λ°°μ΄λ§ 볡μ νκ³ , λ°°μ΄ λ΄λΆμEntry
κ°μ²΄λ€μ 볡μ λμ§ μμλ€.- λ¬Έμ μ : 볡μ λ
HashTable
κ³Ό μλ³ΈHashTable
μ΄ κ°μEntry
κ°μ²΄λ€μ 곡μ νκ² λλ€.
κΉμ 볡μ¬λ₯Ό μν clone()
λ©μλ:
static class HashTable implements Cloneable {
private Entry[] buckets;
private static class Entry {
final Object key;
Object value;
Entry next;
public Entry(Object key, Object value, Entry next) {
this.key = key;
this.value = value;
this.next = next;
}
// μ°κ²° 리μ€νΈλ₯Ό κΉμ 볡μ¬νλ λ©μλ
Entry deepCopy() {
Entry result = new Entry(key, value, next);
Entry p = result;
while (p.next != null) {
p.next = new Entry(p.next.key, p.next.value, p.next.next);
p = p.next;
}
return result;
}
}
@Override
public HashTable clone() {
try {
HashTable result = (HashTable) 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 (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
deepCopy()
λ©μλλ₯Ό ν΅ν΄ κ° λ²ν·μ μ°κ²° 리μ€νΈλ₯Ό 볡μ νλ€.- κ²°κ³Ό: 볡μ λ
HashTable
μ μλ³Έκ³Ό λ 립μ μΈEntry
κ°μ²΄λ€μ κ°μ§κ²λλ€.
- λ°λ³΅λ¬Έ μ¬μ©: μ¬κ· νΈμΆ λμ λ°λ³΅λ¬Έμ μ¬μ©νμ¬ μ€ν μ€λ²νλ‘μ°λ₯Ό λ°©μ§
- μλ‘μ΄
Entry
κ°μ²΄ μμ±: μ°κ²°λ κ°Entry
λ₯Ό μλ‘μ΄ κ°μ²΄λ‘ μμ±νμ¬ λ³΅μ¬νλ€. - μλ³Έκ³Ό 볡μ λ³Έμ λ λ¦½μ± λ³΄μ₯: 볡μ λ κ°μ²΄λ€μ μλ³Έ κ°μ²΄λ€κ³Ό λ 립μ μΌλ‘ λμνλ€.
- μμ±μμμλ μ¬μ μλ μ μλ λ©μλλ₯Ό νΈμΆνλ©΄ μ λ©λλ€.
- λ§μ½
put()
λ©μλλ₯Ό μ΄μ©νμ¬ λ³΅μ νλ€λ©΄,put()
λ©μλλfinal
λλprivate
μΌλ‘ μ μΈλμ΄μΌ ν©λλ€. - μ΄λ νμ ν΄λμ€μμ λ©μλλ₯Ό μ¬μ μνμ¬ μμμΉ λͺ»ν λμμ΄ λ°μνλ κ²μ λ°©μ§ν©λλ€.
- μΈμ΄μ μΈ λͺ¨μκ³Ό μνμ±:
Cloneable
κ³Όclone()
λ©μλλ μ§κ΄μ μ΄μ§ μκ³ κ΅¬ννκΈ° μ΄λ ΅λ€. - μμ 볡μ¬μ κΈ°λ³Έ λμ: κΈ°λ³Έμ μΌλ‘ μμ 볡μ¬κ° μ΄λ£¨μ΄μ Έ κ°λ³ κ°μ²΄λ₯Ό μ λλ‘ λ³΅μ νμ§ λͺ»νλ€.
final
νλμμ μΆ©λ:final
νλλ λ³΅μ¬ ν κ°μ λ³κ²½ν μ μμ΄ λ³΅μ μ λ¬Έμ κ° λ°μνλ€.- μμΈ μ²λ¦¬μ 볡μ‘μ±:
CloneNotSupportedException
λ± λΆνμν μμΈ μ²λ¦¬κ° νμ - μ¬μ μλ λ©μλ νΈμΆ λ¬Έμ :
clone()
λ©μλμμ μ¬μ μλ λ©μλλ₯Ό νΈμΆνλ©΄ λ¬Έμ κ° λ°μνλ€.
Object.clone()
μ λκΈ°νλ₯Ό μ κ²½μ°μ§ μμ λ©μλμ΄λ€.- λμμ± λ¬Έμ κ° λ°μν μ μλ€.
- λ§μΌ
clone()
μ λ§κ³ μΆλ€λ©΄clone()
λ©μλλ₯Ό μ¬μ μνμ¬,CloneNotSupportedException()
μ λμ§λλ‘ νμ. - κΈ°λ³Έ νμ
μ΄λ λΆλ³ κ°μ²΄ μ°Έμ‘°λ§ κ°μ§λ©΄ μ무κ²λ μμ ν νμ μμΌλ
μΌλ ¨λ²νΈ
νΉμκ³ μ ID
μ κ°μ κ°μ κ°μ§κ³ μλ€λ©΄, λΉλ‘ λΆλ³μΌμ§λΌλ μλ‘κ² μμ ν΄μ€μΌ ν¨
{% hint style="info" %} λ³΅μ¬ μμ±μλ λ¨μν μμ κ³Ό κ°μ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μΈμλ‘ λ°λ μμ±μλ₯Ό λ§νλ€. {% endhint %}
Cloneable
μΈν°νμ΄μ€μ clone()
λ©μλ λμ λ³΅μ¬ μμ±μμ λ³΅μ¬ ν©ν°λ¦¬ λ©μλλ₯Ό μ¬μ©νλ κ²μ΄ μ’λ€.
- λ³΅μ¬ ν©ν°λ¦¬ λ©μλ: λ³΅μ¬ μμ±μμ μ μ¬νμ§λ§ μ μ ν©ν°λ¦¬ λ©μλλ‘ κ΅¬νλλ€.
- Cloneableμ μ΄λ―Έ ꡬνν ν΄λμ€λ₯Ό νμ₯νλ€λ©΄ μ΄μ© μ μμ΄ cloneμ μ μλνλλ‘ κ΅¬νν΄μΌ νλ€. κ·Έλ μ§ μμ μν©μμλ
λ³΅μ¬ μμ±μμ λ³΅μ¬ ν©ν°λ¦¬
λΌλ λ λμ κ°μ²΄ λ³΅μ¬ λ°©μμ μ 곡ν μ μλ€.
public class Yum {
private int value;
// λ³΅μ¬ μμ±μ
public Yum(Yum yum) {
this.value = yum.value;
}
}
public class Yum {
private int value;
private Yum(int value) {
this.value = value;
}
// λ³΅μ¬ ν©ν°λ¦¬ λ©μλ
public static Yum newInstance(Yum yum) {
return new Yum(yum.value);
}
}
- μ§κ΄μ μΈ κ°μ²΄ μμ±: μμ±μλ μ μ λ©μλλ₯Ό μ¬μ©νλ―λ‘ κ°μ²΄ μμ± λ°©μμ΄ λͺ ν
- μμ μ±:
Cloneable
μ 볡μ‘ν κ·μ½μ μμ‘΄νμ§ μμΌλ―λ‘ κ΅¬ν μ€μμ μνμ΄ μ λ€. - μ μ°μ±: νμν κ²½μ° λ³΅μ¬ κ³Όμ μμ νλλ₯Ό λ³ννκ±°λ μμ ν μ μλ€.
- μμΈ μ²λ¦¬ κ°μν: λΆνμν μμΈλ₯Ό λμ§μ§ μμΌλ―λ‘ μ¬μ©νκΈ° νΈλ¦¬ν©
- νλ³ν λΆνμ: λ°ν νμ μ΄ λͺ ννλ―λ‘ νλ³νν νμκ° μλ€.
/**
* Constructs a new {@code HashMap} with the same mappings as the
* specified {@code Map}. The {@code HashMap} is created with
* default load factor (0.75) and an initial capacity sufficient to
* hold the mappings in the specified {@code Map}.
*
* @param m the map whose mappings are to be placed in this map
* @throws NullPointerException if the specified map is null
*/
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
- μλ
HashMap
μμ μ 곡νλ λ³΅μ¬ μμ±μλ‘ λ³Ό μ μλ€.
λ μ νν μ΄λ¦μ
λ³ν μμ±μ(conversion constructor)
μλ³ν ν©ν°λ¦¬(conversion factory)
μ΄λ€.
μ΄ λ°©μμ clone()
λ©μλλ³΄λ€ μ¬λ¬ λ©΄μμ λ λ«μ΅λλ€. ArrayList
λ clone()
λ©μλλ₯Ό μ¬μ©ν기보λ€, λ€λ₯Έ 컬λ μ
μ μμλ₯Ό λ°μλ€μ΄λ μμ±μλ₯Ό μ 곡νλ€.
μ£Όμμ΄ ν¬ν¨λ μ½λ μμ :
/**
* μ§μ λ 컬λ μ
μ μμλ₯Ό μμλλ‘ ν¬ν¨νλ 리μ€νΈλ₯Ό μμ±ν©λλ€.
*
* @param c μ΄ λ¦¬μ€νΈμ μΆκ°λ μμλ₯Ό ν¬ν¨νλ 컬λ μ
* @throws NullPointerException μ§μ λ 컬λ μ
μ΄ nullμΈ κ²½μ°
*/
public ArrayList(Collection<? extends E> c) {
// 컬λ μ
μ μμλ₯Ό λ°°μ΄λ‘ λ³νν©λλ€.
elementData = c.toArray();
// 리μ€νΈμ ν¬κΈ°λ₯Ό μ€μ ν©λλ€.
size = elementData.length;
// c.toArray()κ° Object[]λ₯Ό λ°ννμ§ μμ μ μμΌλ―λ‘, λ°°μ΄μ νμ
μ Object[]λ‘ λ³΄μ₯ν©λλ€.
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
μ€λͺ :
- λͺ©μ : μ΄ μμ±μλ μ§μ λ 컬λ μ
c
μ λͺ¨λ μμλ₯Ό ν¬ν¨νλ μλ‘μ΄ArrayList
μΈμ€ν΄μ€λ₯Ό μμ±νλ€λ€. μμλ€μ 컬λ μ μ μ΄ν°λ μ΄ν°κ° λ°ννλ μμλ₯Ό λ°λ₯Έλ€. - μμΈν μ₯μ :
- ν΄λ‘ λ©μ»€λμ¦μ λ¬Έμ ννΌ:
clone()
λ©μλλ μμ 볡μ¬λ‘ μΈν΄ κ°λ³ κ°μ²΄λ₯Ό μ¬λ°λ₯΄κ² 볡μ νμ§ λͺ»νλ λ±μ λ¬Έμ κ° μλ€.- μμ±μλ₯Ό μ¬μ©νλ©΄ 볡μ κ³Όμ μμ μμ ν ν΅μ λ₯Ό ν μ μλ€.
- μΈν°νμ΄μ€ νμ
μμ©:
Collection<? extends E>
λ₯Ό μΈμλ‘ λ°μΌλ―λ‘,List
,Set
λ± λ€μν 컬λ μ μ μΈμλ‘ λ°μ μ μλ€.- μ΄λ₯Ό ν΅ν΄ μμ±μμ νμ© λ²μκ° λμ΄μ§
- νλ³ν λΆνμ:
- λ΄λΆμ μΌλ‘ νμ λ³νμ μ²λ¦¬νλ―λ‘, νΈμΆ μμ λ³λμ νλ³νμ΄ νμ μλ€.
- λ°νμ μ
ClassCastException
μ΄ λ°μν μνμ μ€μΈλ€.
- κ²μ¬ μμΈ μ²λ¦¬ κ°μν:
clone()
λ©μλλCloneNotSupportedException
μ μ²λ¦¬ν΄μΌ νμ§λ§, μ΄ μμ±μλ κ·Έλ° μμΈλ₯Ό λμ§μ§ μμ μ¬μ©μ΄ κ°νΈ
final
νλμ μ¬λ°λ₯Έ μ΄κΈ°ν:- μμ±μλ₯Ό μ¬μ©νλ©΄
final
νλλ₯Ό μ μ ν μ΄κΈ°νν μ μμ§λ§,clone()
μ μμ±μλ₯Ό νΈμΆνμ§ μμΌλ―λ‘final
νλ μ΄κΈ°νμ λ¬Έμ κ° μκΈΈ μ μλ€.
- μμ±μλ₯Ό μ¬μ©νλ©΄
- ν΄λ‘ λ©μ»€λμ¦μ λ¬Έμ ννΌ:
μ¬μ© μμ
// μλ³Έ 컬λ μ
Collection<String> originalCollection = Arrays.asList("μ¬κ³Ό", "λ°λλ", "체리");
// λ³ν μμ±μλ₯Ό μ¬μ©νμ¬ μλ‘μ΄ ArrayList μμ±
ArrayList<String> fruitList = new ArrayList<>(originalCollection);
// μλ‘μ΄ λ¦¬μ€νΈμ μμ μΆκ°
fruitList.add("λ°μ΄νΈ");
// μλ³Έ 컬λ μ
μ λ³κ²½λμ§ μμ
System.out.println("μλ³Έ 컬λ μ
: " + originalCollection); // [μ¬κ³Ό, λ°λλ, 체리]
System.out.println("κ³ΌμΌ λ¦¬μ€νΈ: " + fruitList); // [μ¬κ³Ό, λ°λλ, 체리, λ°μ΄νΈ]
κ°μ²΄ 볡μ¬λ₯Ό νμλ‘ ν λλ
Cloneable
κ³Όclone()
λ©μλ보λ€λ λ³΅μ¬ μμ±μλ λ³΅μ¬ ν©ν°λ¦¬ λ©μλλ₯Ό μ¬μ©νλ κ²μ΄ λ μμ νκ³ κΆμ₯λλ λ°©λ²
Cloneable
μ΄ λͺ°κ³ μ¨ λͺ¨λ λ¬Έμ λ₯Ό λμ§μ΄λ΄€μ λ, μλ‘μ΄ μΈν°νμ΄μ€λ₯Ό λ§λ€ λλ μ λ Cloneableμ νμ₯ν΄μλ μ λλ©°, μλ‘μ΄ ν΄λμ€λ μ΄λ₯Ό ꡬνν΄μλ μ λλ€.
- μλ‘μ΄ ν΄λμ€λ μΈν°νμ΄μ€λ₯Ό λ§λ€ λ
Cloneable
μ ꡬννκ±°λ νμ₯νμ§ λ§μλΌCloneable
μ λ§μ λ¬Έμ μ μ κ°μ§κ³ μμ΄ μ¬μ©μ κΆμ₯νμ§ μλλ€.
- 볡μ κΈ°λ₯μ λ³΅μ¬ μμ±μλ λ³΅μ¬ ν©ν°λ¦¬ λ©μλλ₯Ό μ¬μ©ν΄λΌ
- λ μμ νκ³ μ μ°νλ©°, μ΄ν΄νκΈ° μ½λ€.
- μ΄λ€μ μ½λκ° λͺ
ννκ³ μ΄ν΄νκΈ° μ¬μ°λ©°,
final
νλμλ μΆ©λνμ§ μκ³ , λΆνμν μμΈ μ²λ¦¬λ νλ³νμ΄ νμνμ§ μλλ€.
- λ°°μ΄μ μμΈ
- λ°°μ΄μ
clone()
λ©μλλ₯Ό μ¬μ©νμ¬ λ³΅μ νλ κ²μ΄ κ°μ₯ κΉλνκ³ ν¨μ¨μ
- λ°°μ΄μ
++ native λ©μλ
native: λ©μλλ Cλ C++ κ°μ λ€μ΄ν°λΈ νλ‘κ·Έλλ° μΈμ΄λ‘ μμ±ν λ©μλλ₯Ό μλ―Ένλ€. Java Native Interface(JNI)λΌκ³ λΆλ₯Έλ€. μ¦, Cλ C++μ μ½λλ₯Ό μλ°μμ λΆλ¬ μ¬μ©νλ €λ©΄ native λ©μλλ₯Ό μ μν΄μ λ©μλ λ°λλ₯Ό κ°μ§ μλ λ©μλλ₯Ό ꡬννλ€. (λ©μλ λ°λκ° dll (Unixμμ so) νμΌλ‘ λμ΄ μμ΄ λ°νμ μμ dll νμΌμ System.loadLibrary λ©μλκ° μννμ¬ classpath κ²½λ‘μμ νλΌλ―Έν°μ νμΌμ λ©λͺ¨λ¦¬μ λ‘λ©)
μ°Έκ³ λ° μΌλΆ κ°μ Έμ€κΈ° : https://jake-seo-dev.tistory.com/31#%EB%B-%B-%EC%--%AC%--%EC%--%-D%EC%--%B-%EC%-E%--%EC%--%--%--%EB%B-%B-%EC%--%AC%--%ED%-C%A-%ED%--%B-%EB%A-%AC%EB%A-%-C%--clone--%--%EA%B-%AC%ED%--%--%ED%--%--%EA%B-%B-
Footnotes
-
AssertionErrorλ 무μμΈκ°μ?
AssertionError
λ μλ°μμ μλ¬(Error)μ ν μ’ λ₯λ‘, μ£Όλ‘ νλ‘κ·Έλ¨μ λ Όλ¦¬μ μΈ μ€λ₯κ° λ°μνμ λ μ¬μ©λ©λλ€. μ΄ μλ¬λ μΌλ°μ μΌλ‘ κ°λ°μκ° μμΈ‘ν μ μλ μν©μ΄ λ°μνμ λ μ΄λ₯Ό μ리기 μν΄ λμ§λλ€.1. AssertionErrorμ λͺ©μ
- κ°λ° μ€μλ§ μ¬μ©:
AssertionError
λ μ£Όλ‘ κ°λ° λ° λλ²κΉ λ¨κ³μμ νλ‘κ·Έλ¨μ λ΄λΆ μνλ₯Ό κ²μ¦νκΈ° μν΄ μ¬μ©λ©λλ€. - λΆκ°λ₯ν μν©μ λνλ: μ½λμμ μ λλ‘ λ°μν΄μλ μ λλ μν©μ΄ λ°μνμ λ μ΄λ₯Ό μ리기 μν΄ μ¬μ©ν©λλ€.
- μμΈ μ²λ¦¬μ κ°μν: κ²μ¬ μμΈ(checked exception)λ₯Ό μ²λ¦¬ν΄μΌ νλ λ²κ±°λ‘μμ νΌνκΈ° μν΄ μ¬μ©λ©λλ€.
- κ°λ° μ€μλ§ μ¬μ©: