[λμμΈν¨ν΄] νλ‘ν νμ ν¨ν΄(Prototype Pattern)
νκ·Έ: Design Pattern, Java, Refactoring
μΉ΄ν κ³ λ¦¬: Design Pattern
νλ‘ν νμ ν¨ν΄
- νλ‘ν νμ ν¨ν΄μ λν΄ μμλ³΄κ³ μ¬μ© μ¬λ‘λ₯Ό μ΄ν΄λ΄ λλ€.
μ μ
κΈ°μ‘΄ μΈμ€ν΄μ€λ₯Ό 볡μ νμ¬ μλ‘μ΄ μΈμ€ν΄μ€λ₯Ό λ§λλ λ°©λ²
- 볡μ κΈ°λ₯μ κ°μΆκ³ μλ κΈ°μ‘΄ μΈμ€ν΄μ€λ₯Ό νλ‘ν νμ μΌλ‘ μ¬μ©ν΄ μ μΈμ€ν΄μ€λ₯Ό λ§λ€ μ μλ€.
μ£Όμ κ΅¬μ± μμ
κ°μ²΄λ₯Ό 볡μ ν λ μκΈ°λ λ¬Έμ μ
κ°μ²΄λ₯Ό 볡μ νλ κ²μ μκ°μ²λΌ κ°λ¨ν μΌμ΄ μλ μ μλ€. λ€μκ³Ό κ°μ λͺκ°μ§ λ¬Έμ κ° μλλ° νλμ© μ΄ν΄λ³΄μ.
κ°μ²΄ μΈλΆμμ private νλλ₯Ό 볡μ¬ν μ μλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // Getter public String getName() { return name; } public int getAge() { return age; } } public class Main { public static void main(String[] args) { Person person1 = new Person("Alice", 30); // λΉκ³΅κ° νλ μ κ·Ό μλ - μ€λ₯ λ°μ // String name = person1.name; // μ»΄νμΌ μλ¬ // int age = person1.age; // μ»΄νμΌ μλ¬ // 볡μ λ³Έμ μμ±νλ €κ³ νμ§λ§ λΉκ³΅κ° νλμ μ κ·Όν μ μμ Person person2 = new Person(person1.getName(), person1.getAge()); System.out.println(person1.getName() + ", " + person1.getAge()); System.out.println(person2.getName() + ", " + person2.getAge()); } }
κ°μ²΄μ 볡μ λ³Έμ μμ±νλ €λ©΄ κ°μ²΄μ ν΄λμ€λ₯Ό μμμΌ νλ€.
ν΄λμ€ μμ‘΄λκ° λμμ§λ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Employee { private String name; private int salary; public Employee(String name, int salary) { this.name = name; this.salary = salary; } // Getter public String getName() { return name; } public int getSalary() { return salary; } // λ³΅μ¬ μμ±μ νμ public Employee(Employee other) { this.name = other.name; this.salary = other.salary; } } public class Main { public static void main(String[] args) { Employee emp1 = new Employee("Bob", 50000); // 볡μ λ³Έμ μμ±νλ €λ©΄ Employee ν΄λμ€μ μμ‘΄ Employee emp2 = new Employee(emp1); // Employee ν΄λμ€μ μμ‘΄ System.out.println(emp1.getName() + ", " + emp1.getSalary()); System.out.println(emp2.getName() + ", " + emp2.getSalary()); } }
μΈν°νμ΄μ€ κΈ°λ° μ€κ³ λ¬Έμ
ꡬ체 ν΄λμ€μ μμ‘΄νμ§ μκ³ κ°μ²΄λ₯Ό 볡μ νκΈ° μ΄λ ΅λ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 interface Copyable { Copyable copy(); } class Student implements Copyable { private String name; private int grade; public Student(String name, int grade) { this.name = name; this.grade = grade; } @Override public Copyable copy() { return new Student(this.name, this.grade); } // Getter public String getName() { return name; } public int getGrade() { return grade; } } public class Main { public static void main(String[] args) { Copyable student1 = new Student("Charlie", 10); // μΈν°νμ΄μ€λ₯Ό ν΅ν΄μλ ꡬ체μ μΈ ν΄λμ€μ μ κ·Όν μ μμ // Student student2 = (Student) student1.copy(); // λ€μ΄μΊμ€ν νμ - μ μ°μ± μ ν Copyable student2 = student1.copy(); // Copyable μΈν°νμ΄μ€λ‘λ ꡬ체μ μΈ νλ μ κ·Ό λΆκ° // student2κ° Student νμ μΈμ§ νμΈ ν μΊμ€ν νμ if (student2 instanceof Student) { Student copiedStudent = (Student) student2; System.out.println(copiedStudent.getName() + ", " + copiedStudent.getGrade()); } } }
μμ κ°μ λ¬Έμ λ₯Ό ννΌνλ©΄μλ 볡μ ν μ μλ λ°©λ²μ λν΄ μμ보μ.
νλ‘ν νμ ν¨ν΄ μμ
μ°μ νλ‘ν νμ ν¨ν΄μ ꡬμ±μμλλ‘ μΈν°νμ΄μ€λ₯Ό λ§λ λ€. μ μΈν°νμ΄μ€κ° νμνμ§μ λν΄μ μ½λλ₯Ό ν΅ν΄ μμ λ³΄κ² λ€.
1
2
3
public interface Prototype {
Prototype clone();
}
κ·Έ ν μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€ λ΄μμ clone() λ©μλλ₯Ό μ¬μ μνλ€.
GameCharacter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class GameCharacter implements Prototype {
private String name;
private int level;
private String profession;
public GameCharacter(String name, int level, String profession) {
this.name = name;
this.level = level;
this.profession = profession;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
// clone μ¬μ μ
@Override
public Prototype clone() {
return new GameCharacter(name, level, profession);
}
@Override
public String toString() {
return "GameCharacter [name=" + name + ", level=" + level + ", profession=" + profession + "]";
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof GameCharacter))
return false;
GameCharacter that = (GameCharacter) o;
return level == that.level && Objects.equals(name, that.name) && Objects.equals(profession,
that.profession);
}
}
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Client {
public static void main(String[] args) {
List<Prototype> characters = new ArrayList<>(); // μλ³Έ μ μ₯μ© λ¦¬μ€νΈ
List<Prototype> charactersCopy = new ArrayList<>(); // 볡μ μ μ₯μ© λ¦¬μ€νΈ
// μλ³Έ κ°μ²΄ μμ±
GameCharacter originalCharacter = new GameCharacter("Archer", 10, "Archer");
characters.add(originalCharacter);
// 볡μ κ°μ²΄ μμ±
GameCharacter clonedCharacter = (GameCharacter) originalCharacter.clone();
characters.add(clonedCharacter);
// 볡μ κ°μ²΄μ μμ± λ³κ²½
clonedCharacter.setName("Mage");
clonedCharacter.setProfession("Mage");
// μΆλ ₯
System.out.println("Original Character: " + originalCharacter);
System.out.println("Cloned Character: " + clonedCharacter);
System.out.println();
cloneAndCompare(characters, charactersCopy);
}
private static void cloneAndCompare(List<Prototype> characters, List<Prototype> charactersCopy) {
// μ΄ λΆλΆμ΄ μΈν°νμ΄μ€λ₯Ό μ¬μ©ν μ΄μ λ€.
for (Prototype character : characters) {
charactersCopy.add(character.clone());
}
for (int i = 0; i < characters.size(); i++) {
if (characters.get(i) != charactersCopy.get(i)) {
System.out.println(i + ": μλ‘ λ€λ₯Έ μΊλ¦ν° κ°μ²΄λ€. (yay!)");
if (characters.get(i).equals(charactersCopy.get(i))) {
System.out.println(i + ": κ·Έλ¦¬κ³ μλ‘ κ°μ κ°μ²΄λ€.(yay!)");
} else {
System.out.println(i + ": κ·Έλ¬λ μλ‘ λ€λ₯Έ κ°μ²΄λ€. (booo!)");
}
} else {
System.out.println(i + ": μλ‘ κ°μ νλ‘ν νμ
κ°μ²΄λ€. (booo!)");
}
}
}
}
μ μ½λμμ characters
λ°°μ΄μμ κ°μ κΊΌλ΄ κ°κ°μ clone() ν λ ꡬ체μ μΈ ν΄λμ€λ₯Ό λͺ°λΌλ μΌκ΄λ λ°©μμΌλ‘ μ½λλ₯Ό μμ± κ°λ₯νλ€. clone() λ΄λΆμμ ꡬ체 ν΄λμ€κ° λ§λ€μ΄μ Έ 볡μ λλ€.
1
2
3
for (Prototype character : characters) {
charactersCopy.add(character.clone());
}
μΆλ ₯κ²°κ³Ό
1
2
3
4
5
6
7
Original Character: GameCharacter [name=Archer, level=10, profession=Archer]
Cloned Character: GameCharacter [name=Mage, level=10, profession=Mage]
0: μλ‘ λ€λ₯Έ μΊλ¦ν° κ°μ²΄λ€. (yay!)
0: κ·Έλ¦¬κ³ μλ‘ κ°μ κ°μ²΄λ€.(yay!)
1: μλ‘ λ€λ₯Έ μΊλ¦ν° κ°μ²΄λ€. (yay!)
1: κ·Έλ¦¬κ³ μλ‘ κ°μ κ°μ²΄λ€.(yay!)
clone() ν©ν 리 λ©μλ μμμ μλ‘μ΄ κ°μ²΄λ₯Ό 리ν΄νκ³ μκΈ° λλ¬Έμ μλ‘ λ€λ₯Έ μ£Όμκ°μ κ°μ§ κ°μ²΄λ€. κ·Έλ¦¬κ³ κ°μ²΄ λ΄λΆ νλκ°μ΄ κ°μ κ²½μ° κ°μ κ°μ²΄λ‘ 보기μν΄ equals() λ₯Ό μ¬μ μ νμκΈ° λλ¬Έμ μλ‘ κ°μ κ°μ²΄μμ΄ λ³΄μ₯λλ€.
java μμ μ§μνλ Cloneable μΈν°νμ΄μ€
java μμλ clone() μ μν Java Native Interface λ₯Ό μ§μνλ€. ν΄λΉ λ©μλ ꡬν μ super.clone()
μ νΈμΆνκ² λλ©΄ λ΄λΆμ μΌλ‘ μμ 볡μ¬κ° μ§νλλ€.
1
2
@HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
ν΄λΉ λ©μλλ Object ν΄λμ€μ μκ³ , 볡μ λ©μλκ° νμν ν΄λμ€μμ μ¬μ μ νλ©΄ λλλ°, κ·Έ ν΄λμ€λ Cloneable μ΄λΌλ μΈν°νμ΄μ€λ₯Ό ꡬννκ³ μμ΄μΌ νλ€.
1
2
public interface Cloneable {
}
Cloneable μΈν°νμ΄μ€λ μλ¬΄λ° λ©μλλ μ‘΄μ¬νμ§ μλλ°, μ΄λ₯Ό λ§μ»€ μΈν°νμ΄μ€(Marker Interface)λΌ νλ€. λ§μ»€ μΈν°νμ΄μ€κ° ꡬνλ ν΄λμ€λ νΉμ μμ±μμ java κ° μ μ μλλ‘ ν΄μ€λ€.
Cloneable μΈν°νμ΄μ€κ° ꡬνλμ΄ μλ ν΄λμ€λ clone() λ©μλλ₯Ό νΈμΆν μ μλ€λ μ격μ΄λΌκ³ 보면λλ€. λ§μ½ λ§μ»€ μΈν°νμ΄μ€κ° μλ μνμμ clone() μ νΈμΆνκ² λλ©΄ CloneNotSupportedException
μ΄ λ°μνλ€.
μ§λ ¬ν κ°μ²΄μ μ§λ ¬νκ° κ°λ₯ν¨μ μ리기μν΄ λΆμ΄λ Serializable μΈν°νμ΄μ€μ κ²½μ°λ λ§μ»€ μΈν°νμ΄μ€λ€.
JNI
Java Native Interface λ java ꡬνλμ§ μμ μΌλΆ νλ‘μΈμ€λ₯Ό κ°λ₯νκ² λ§λ λ€. μλ₯Ό λ€μ΄ νλμ¨μ΄ μ‘°μ λͺ λ Ήμ΄λ μ§μ μ μΈ OS API λͺ λ Ή μΆμ² : https://medium.com/@sarafanshul/jni-101-introduction-to-java-native-interface-8a1256ca4d8e
μμλ³΅μ¬ / κΉμ볡μ¬
κ°μ²΄μ 볡μ μ νμ ν¨κ» λ±μ₯νλ μ£Όμ μ€ νλκ° shallow copy / deep copy λΌκ³ μκ°νλ€. κ°λ¨ν μ 리νλ©΄
- shallow copy : κ°μ²΄μ μ΅μμ λ λ²¨λ§ λ³΅μ¬. νμ κ°μ²΄λ μ°Έμ‘°λ₯Ό 곡μ . μλ³Έ κ°μ²΄λ 볡μ¬λ κ°μ²΄μ λ³κ²½μ΄ μλ‘μκ² μν₯μ λ―ΈμΉ μ μλ€.
- deep copy : κ°μ²΄ μ 체λ₯Ό μ¬κ·μ μΌλ‘ 볡μ¬. νμ κ°μ²΄κΉμ§ λͺ¨λ λ 립μ μΈ λ³΅μ¬λ³Έ μμ±. μλ‘ μν₯μ λ―ΈμΉμ§ μλλ€.
μ₯μ κ³Ό λ¨μ
- μ₯μ
- 볡μ‘ν κ°μ²΄λ₯Ό λ§λλ κ³Όμ μ μ¨κΈΈ μ μλ€.
- κΈ°μ‘΄ κ°μ²΄λ₯Ό 볡μ νλ κ³Όμ μ΄ μ μΈμ€ν΄μ€λ₯Ό λ§λλ κ²λ³΄λ€ λΉμ©λ©΄μμ ν¨μ¨μ μΌ μλ μλ€.
- μΆμμ μΈ νμ μ 리ν΄ν μ μλ€.
- λ¨μ
- 볡μ ν κ°μ²΄λ₯Ό λ§λλ κ³Όμ μμ²΄κ° λ³΅μ‘ν μ μλ€. (μν μ°Έμ‘°κ° μλ κ²½μ°)
μλ°μμ μ°Ύμ보λ νλ‘ν νμ
ArrayList.clone()
ArrayList λ₯Ό 볡μ¬ν λ clone() λ©μλλ₯Ό μ¬μ©νλ©΄ λλ€.
ArrayList λ Cloneable μΈν°νμ΄μ€λ₯Ό ꡬννκ³ μλ€.
κ·Έλ¬λ μ΄ λ°©λ²μ μ μ°μ΄μ§ μλλ€. μλνλ©΄ λ³΄ν΅ ArrayList λ₯Ό λ°μλ μλμ²λΌ μΈν°νμ΄μ€ νμ μΌλ‘ λ°κΈ° λλ¬Έμ΄λ€.
1
List<Item> items = new ArrayList<>();
List μΈν°νμ΄μ€μλ clone() λ©μλκ° μ‘΄μ¬νμ§ μλλ€.
νλ‘ν νμ ν¨ν΄μ μ°μ§ μκ³ μμ±μλ‘ λ³΅μ¬
ArrayList μ μμ±μ μ€μ 컬λ μ νμ μ λ°λ μμ±μκ° μλ€. μΈμλ‘ μ λ¬νλ©΄ 볡μ λλ€.
ArrayList
1
2
3
4
5
6
7
8
9
10
11
12
13
public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
Client
1
List<Item> clone = new ArrayList<>(items); // νλΌλ―Έν°λ‘ 컬λ μ
νμ
μ μ λ¬νλ©΄ 볡μ λλ€.
ν΄λΉ λ©μλ μ€κ°μ Arrays.copyOf() λ©μλλ₯Ό ν΅ν΄ νλΌλ―Έν°λ‘ λ겨λ°μ 컬λ μ μ 볡μ¬νλ€.
리νλμ μ¬μ©
리νλμ μ μ΄μ©ν λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ©΄ 볡μ‘ν μ½λλ₯Ό μ§μ μ§μ§ μμλ μ½κ² 볡μ κ° κ°λ₯νλ€. 첫λ²μ§Έ μΈμλ‘ μ€λ νκ² κ°μ²΄λ₯Ό λλ²μ§Έ μΈμμ νμ μΌλ‘ λ³νμμΌμ€λ€.
리νλμ κ΄λ ¨ν΄μλ ν΄λΉ κΈμμ μ 리νλ€.
ModelMapper λΌμ΄λΈλ¬λ¦¬
1
2
ModelMapper modelMapper = new ModelMapper();
GithubIssueData githubIssueData = modelMapper.map(githubIssue, GithubIssueData.class);
ObjectMapper λΌμ΄λΈλ¬λ¦¬
1
Map<String, Object> response = om.readValue(response, Map.class);
ObjectMapper λ ν νλ‘μ νΈμμ OAuth μΈμ¦ μ νλ«νΌ λ³ μμ΄ν JSON μ νμ±νκΈ° μν΄ μ¬μ©νλ κ²½νμ΄ μλ€. (μ½λ보기)
Gson λΌμ΄λΈλ¬λ¦¬
볡μ ν μΈμ€ν΄μ€λ₯Ό GsonBuilder μ toJson() μ νλΌλ―Έν°λ‘ λ겨주면 μλ‘μ΄ JSON ννλ‘ λ°νν΄μ€λ€. μλ μ½λλ νλ‘μ νΈμμ μ¬μ©νλ μ½λμ μΌλΆλΆμ΄λ€. (μ 체 μ½λ보기)
1
2
3
4
5
// Result.class
@Override
public String toString() {
return new GsonBuilder().serializeNulls().create().toJson(this);
}
Rest api λ°ν κ°μ²΄μ toString μ μ¬μ μνκ³ JSON κ°μ²΄λ‘ 리ν΄νκΈ° μν΄ GsonBuilder λ₯Ό μ¬μ©νλ€. ν΄λΌμ΄μΈνΈ μͺ½ μ½λλ μλμ κ°μ΄ μΌλ°μ μΈ toString μ νΈμΆνλ―μ΄ νλ©΄ JSON ννλ‘ λ°νν μ μλ€.
1
2
3
4
5
@PostMapping("add")
public String add(@RequestBody @Valid CodeRequestDto codeRequestDto) throws Exception {
codeService.add(codeRequestDto);
return new Result<>().setResultData(codeService.list(Paging.builder().build())).toString();
}
μλμμ μ΄ν΄λ³Ό μ§λ ¬ν λ°©μκ³Ό κ°λ€κ³ 보면 λλ€.
κ°μ²΄λ₯Ό 볡μ νλ λ€μν λ°©λ²
λ³΅μ¬ μμ±μ
λ³΅μ¬ μμ±μ
ν΄λμ€ λ΄λΆμ
λ³΅μ¬ μμ±μ
λ₯Ό μ μνμ¬, ν΄λΉ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό 맀κ°λ³μλ‘ λ°μ νλ κ°μ 볡μ¬νλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Person { private String name; private int age; // μμ±μ public Person(String name, int age) { this.name = name; this.age = age; } // λ³΅μ¬ μμ±μ public Person(Person other) { this.name = other.name; this.age = other.age; } // // Getter κ° μμ΄λ private νλ λ³΅μ¬ κ°λ₯ // public String getName() { // return name; // } // // public int getAge() { // return age; // } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } public class Main { public static void main(String[] args) { Person person1 = new Person("Alice", 30); Person person2 = new Person(person1); // λ³΅μ¬ μμ±μ μ¬μ© System.out.println(person1); System.out.println(person2); } }
μ§λ ¬ν
μ§λ ¬ν
κ°μ²΄λ₯Ό μ§λ ¬νν ν μμ§λ ¬ννλ λ°©λ². μ΄ λ°©λ²μ κΈ°μ‘΄ κ°μ²΄μμ μ°Έμ‘°κ° λμ΄μ Έ κΉμ 볡μ¬λ₯Ό 보μ₯νλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import java.io.*; public class MyClass implements Serializable { private int field1; private String field2; public MyClass deepCopy() { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bis); return (MyClass) in.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return null; } } // κΈ°ν λ©μλ λ° μ κ·Όμ }μλ°μ€ν¬λ¦½νΈμμλ
JSON.stringify()
μJSON.parse()
λ₯Ό ν΅ν΄ κ°λ₯νλ€.
1 2 3 4 5 6 7 8 9 10 11 12 const obj = { a: 1, b: { c: 2, }, }; const copiedObj = JSON.parse(JSON.stringify(obj)); copiedObj.b.c = 3 obj.b.c === copiedObj.b.c //false
ν©ν 리 λ©μλ
ν©ν 리 λ©μλ
ν΄λμ€μ μμ‘΄μ±μ μ€μΌ μ μλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public interface Copyable { Copyable copy(); } public class MyClass implements Copyable { private int field1; private String field2; @Override public MyClass copy() { return new MyClass(this); } // λ³΅μ¬ μμ±μ public MyClass(MyClass other) { this.field1 = other.field1; this.field2 = other.field2; } // κΈ°ν λ©μλ λ° μ κ·Όμ }
μ 리
νλ‘ν νμ ν¨ν΄μ λ€λ₯Έ ν¨ν΄λ€μ λΉν΄ κ°λ¨νλ€. 미리 λ§λ€μ΄ λμ νλ‘ν νμ κ°μ²΄λ₯Ό 볡μ νμ¬ μλ‘μ΄ κ°μ²΄λ₯Ό μμ±νλ ν¨ν΄μ΄λ€. κ°μ²΄ μμ± μ λ§€λ² DB λ₯Ό μ‘°νν΄μΌ νλ λ±κ³Ό κ°μ΄ μμ± λΉμ©μ΄ ν° κ²½μ° μ¬μ©ν μ μμ κ² κ°λ€.
κ·Έλ¬λ ννλ κ°λ¨νμ§λ§ νμ
μμ μ°λ €λ©΄ clone() λ©μλλ₯Ό μ΄λ»κ² μμ±ν΄μΌ ν μ§ μκ°μ ν΄μΌλ κ² κ°λ€.
νΉν java μμ μ§μνλ Cloneable μ κΈ°λ³Έμ μΈ κ΅¬ν λ°©μ(super.clone()
)μ μμ 볡μ¬μμ μΈμ§νκ³ μμ΄μΌ νκ³ , λ§μ½ κΉμ 볡μ¬λ₯Ό ꡬνν΄μΌ νλ κ²½μ°, κ°μ²΄μ λͺ¨λ νμ κ°μ²΄λ€λ μ¬λ°λ₯΄κ² 볡μ λμ΄μΌ νλ―λ‘ κ΅¬νμ΄ κΉλ€λ‘μΈ μ μλ€.
λν 볡μ λ κ°μ²΄κ° νλ‘ν νμ
κ°μ²΄μ λ°μ νκ² μ°κ΄λμ΄ μμ΄, λ§μ½ μλ³Έ κ°μ²΄μ λ΄μ©μ΄ λ³κ²½λλ©΄ μλ‘μ΄ κ°μ²΄λ₯Ό λ§λ€κΈ° μν΄ νλ‘ν νμ
μ κ°±μ ν΄μΌ ν μλ μλ€.
λκΈλ¨κΈ°κΈ°