📜 ⬆️ ⬇️

How to clone an object?

To clone an object in Java, you can use three methods:
  1. Redefining the clone () method and implementing the Cloneable () interface;
  2. Using copy constructor;
  3. Use the clone mechanism for serialization.

Now in order. The first method implies that you will use the mechanism of the so-called “surface cloning” and take care of the cloning of object fields. The clone() method in the parent Object class is protected, so overriding it with the declaration as public is required. It returns an instance of the object with copied primitive fields and links. And it turns out that the original and its clone of the reference field indicate the same objects. The example below shows how the field at the original object and the clone simultaneously changes.

 public class CloneTest{ static class Person implements Cloneable{ String name; int age; Car car; Person(Car car,int age,String name) { this.car = car; this.age = age; this.name = name; } @Override public String toString() { return this.name+" {" + "age=" + age + ", car=" + car + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } static class Car{ public String color; Car(String color) { this.color = color; } @Override public String toString() { return "{" + "color car='" + color + '\'' + '}'; } } public static void main(String[] args) throws CloneNotSupportedException { Car car = new Car("Green"); Person person=new Person(car,25,"Mike"); Person clone = (Person) person.clone(); System.out.println(person); System.out.println(clone); clone.name=new String("Ivan"); clone.car.color="red"; System.out.println(person); System.out.println(clone); } } : Mike {age=25, car={color car='Green'}} Mike {age=25, car={color car='Green'}} Mike {age=25, car={color car='red'}} Ivan {age=25, car={color car='red'}} 

From the example above, it can be seen that in the clone and the original, the state of one of the fields changes simultaneously. The following method is to use the copy constructor:

 public class Person { private int age; private String name; public Person(int age, String name){ this.age=age; this.name=name; } //   public Person(Person other) { this(other.getAge(), other.getName()); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}'; } public static void main(String[] args) { Person original = new Person(18, "Grishka"); Person clone = new Person(original); System.out.println(original); System.out.println(clone); } } : Person{age=18, name='Grishka'} Person{age=18, name='Grishka'} 

The class describes a constructor that takes an object of the same class and initializes the fields of the new object with the values ​​of its fields. A class developer should take care of the implementation of field initialization.

But both of the above methods are full of potential errors and in fact create a copy of the object. The most convenient and flexible way to clone is the serialization mechanism. It consists in saving an object into a stream of bytes, followed by exhumation of it from there. For example, let's invite the cat Vaska, he is waiting for a couple of experiments:
')
 import java.io.*; class Cat implements Serializable{ private String name; private String color; private int age; public Cat(String name, String color, int age) { this.name = name; this.color = color; this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + ", color='" + color + '\'' + ", age=" + age + '}'; } } public class BasketCats{ public static void main(String[] args) throws IOException, ClassNotFoundException { Cat vaska = new Cat("Vaska","Gray",4); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream ous = new ObjectOutputStream(baos); //        () ous.writeObject(vaska); ous.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); //         Cat cloneVaska = (Cat)ois.readObject(); System.out.println(vaska); System.out.println(cloneVaska); System.out.println("*********************************************"); cloneVaska.setColor("Black"); //       ,         System.out.println(vaska); System.out.println(cloneVaska); } } : Cat{name='Vaska', color='Gray', age=4} Cat{name='Vaska', color='Gray', age=4} ********************************************* Cat{name='Vaska', color='Gray', age=4} Cat{name='Vaska', color='Black', age=4} 

Not a single cat suffered as a result of the tests, we see that Vaska was saved to the stream, from which the independent clone was then restored. If there is no special need to process fields during cloning of objects, then serialization is the most preferable option for this purpose.

Source: https://habr.com/ru/post/246993/


All Articles