Топ-100Метод Clone и его переопределение - CodOrbits
LogoCodOrbits

Раздел: Java Core

Раздел охватывает ключевые возможности языка Java: аннотации, исключения, generics, лямбда-выражения, интерфейсы и другие базовые концепции.

Все разделы
Иконка Java Core

Метод Clone и его переопределение

Last updated: 5 мая 2025 г.

Второй метод Object это метод clone, который клонирует объект.

Происходит копирование всех полей клонируемого объекта в новый объект-клон.

Но по умолчанию методом clone в новый объект копируются только примитивные поля объекта, а ссылочные нет, поэтому clone тоже нужно переопределять.

В Java управление объектами осуществляется с помощью ссылочных переменных, и нет оператора для фактического копирования объекта, поэтому и существует clone.


Переопределение Clone

Напрямую вызвать clone у какого либо объекта в main нельзя, так как метод clone внутри Object объявлен protected.

Search Icon

Поэтому для того чтобы вызвать clone у какого либо объекта его всегда нужно переопределять.

То есть имеется ввиду, что даже чтобы использовать стандартную реализацию clone, которая копирует только примитивные поля всё равно нужно сделать минимальное переопределение clone, как это сделано в классе SomeClass ниже.

Создадим два класса, в которых будем переопределять clone.

Все классы, которые переопределяют clone должны реализовывать интерфейс Cloneable. То есть видим ниже в примере программы implements Cloneable

Пример программы:

1import java.util.*;
2
3class SomeClass implements Cloneable {
4    int someVar;
5    SomeClass(int someVar){
6        this.someVar = someVar;
7    }
8
9    //неопределим clone для SomeClass
10    @Override
11    public SomeClass clone() throws CloneNotSupportedException{
12        //Слово super это супер класс то есть класс
13        // от которого наследует текущий класс
14        //Текущий класс наследует от Object.
15        //Слово super это ссылка на родительский класс Object.
16
17        //super.clone() – через супер класс клонируем
18        //текущий объект. Как уже было сказано
19        //у нового объекта copy копируются только примитивные
20        //поля объекта SomeClass. В нашем случае someVar.
21        Object obj = super.clone();
22        //Теперь новый объект clone SomeClass пока типа Object
23        //нам нужно привести его к SomeClass.
24        SomeClass someclass = (SomeClass)obj;
25        //Мы можем это сделать так как
26        //SomeClass наследует от Object.
27        //class SomeClass – extends Object;
28        //А значит имеет в своем составе
29        //все поля и методы SomeClass и в него были
30        //скопированы все НЕ ссылочные поля то есть someVar
31
32        //Ссылочных полей здесь нет
33        //поэтому такого переопределения достаточно
34
35        return someclass;//возвращаем клон
36    }
37
38    public String toString(){
39        return "SomeClass{"+ "someVar=" + someVar +};
40    }
41}
42
43class MyClass implements Cloneable {
44    int myA;
45    SomeClass myB;
46
47    MyClass(int myA, SomeClass myB){
48        this.myA = myA;
49        this.myB = myB;
50    }
51
52    //clone должен копировать как простые
53    //так и ссылочные типы объекта
54    @Override
55    public MyClass clone() throws CloneNotSupportedException{
56        //Здесь для клонирования не ссылочных полей
57        //объекта MyClass производится те же действия
58        //что и в предыдущем классе.
59        Object obj = super.clone();
60        MyClass myclass = (MyClass)obj;
61
62        //В этом классе уже есть ссылочное поле это myB,
63        //его нужно клонировать. Для этого
64        //мы должны вызвать метод clone() из переопределения
65        //SomeClass. Он клонирует все примитивные поля
66        //из объекта myB, который является объектом
67        //SomeClass, который мы сейчас клонировали.
68        //И возвращает myclass, который является клоном.
69        myclass.myB = myB.clone();
70
71        return myclass;
72    }
73
74    public String toString(){
75        return "MyClass{" + "myA=" + myA + ", myB=" + myB +};
76    }
77}
78
79public class CloneLesson {
80    public static void main(String[] args)
81    throws CloneNotSupportedException {
82        //Создаем объект SomeClass и объект MyClass
83        SomeClass someClass = new SomeClass(10);
84        MyClass myclass = new MyClass(10,someClass);
85        //клонируем myclass.
86        MyClass myclass1 = myclass.clone();
87
88        //Выведем на консоль поля клонируемого
89        //объекта и клона.
90        System.out.println(myclass);
91        //Как можно увидеть по результатам все поля
92        //примитивного типа и все типы ссылочные
93        //очень someClass из myclass.
94        System.out.println(myclass1);
95
96        //Теперь самое главное. Нужно точно убедиться
97        //что объекты myclass и myclass1 не ссылаются на один
98        //и тот же объект и тогда точно можно будет сказать
99        //что клонирование прошло успешно. Для этого создадим
100        //новый объект someClass и присвоим его полю myB
101        //объекта myclass1. Если клонирование прошло успешно
102        //то объект someClass никак не должен измениться
103        //в объекте myclass и убедимся что это не произошло.
104        //Если клонирование прошло успешно то объекты
105        //myclass и myclass1 будут разные, что они и отдельны.
106        someClass = new SomeClass(12);
107        myclass1.myB = someClass;
108        System.out.println(myclass);
109        System.out.println(myclass1);
110
111        //Теперь изменим ссылочное поле в myclass1
112        //и убедимся что это не изменило myclass
113        myclass1.myB.someVar = 12;
114        System.out.println(myclass);
115        System.out.println(myclass1);
116    }
117}

Вывод:


Следующие уроки

Метод Equals и его переопределение

16
мин.

Similar Articles Icon
Divider

Метод hashCode и его переопределение

16
мин.

Similar Articles Icon
Divider

Коллекции. Интерфейс List

10
мин.

Similar Articles Icon