JAVA deep and shallow copy and prototype patterns

What is copy

What is copy, popular is the copy and paste we used to say, that is we use most development mode, CV development mode, CTRL + C and CTRL + V development mode, why everyone love this kind of development mode, because the high efficiency development mode, if there is no CV function, even if have a ready-made code, you also get one line copy, It takes a lot of time, but the CV only takes a few seconds, and the same function is reduced by a thousand times.

What is deep copy and shallow copy

Shallow copy

A shallow copy is whether the object we copy is in the same memory address as the previous object. When the original object is changed, the contents of the copied object are also changed.

As shown in the figure above, after object A shallow copies object B, the list of object A is modified. Object B does not need to be modified, and the list of object B is also modified accordingly. The example code is as follows

The Person class * * * *Copy the code
Public class Person implements Cloneable{// Implements Cloneable; List<Integer> List; public Person(List<Integer> list) { this.list = list; } public List<Integer> getList() { return list; } public void setList(List<Integer> list) { this.list = list; } / / @ Override clone method protected Object clone () throws CloneNotSupportedException {return. Super clone (); }}Copy the code

The test class

List<Integer> list =new ArrayList<>(); list.add(1); list.add(2); Person person =new Person(list); Person clone = (Person)person.clone(); System.out.println(person.getList()== Clone.getList()); Println ("cloneList= "+ cloneList=" + Cloner.getList ())); list.add(3); person.setList(list); System.out.println("cloneList= "+ cloneList. GetList ()); System.out.println("person = " + person.getList());Copy the code

The results of

CloneList = [1, 2] cloneList= [1, 2] cloneList= [1, 2] cloneList= [1, 2] cloneList= [1, 2] 3] person = [1, 2, 3] person = [1, 2, 3Copy the code

Deep copy

Strictly speaking, deep copy is the real sense of copy and paste, we copy things on the web page after the local modification will not affect the original, the same as the original based on the modification will not affect the copied, the original and copy in addition to the initial value of the same, are two independent individuals.Deep copy schematicAs shown in the figure above, when object A deeply copies object B and the list of object A is modified, the list of object B will not be modified accordingly. Serializable Serializable Serializable Serializable Serializable Serializable Serializable Serializable Serializable Serializable Serializable Serializable Serializable The example code is as followsThe Person class

Public class Person implements Cloneable, Serializable {// Implements Serializable interface List<Integer> List; public Person(List<Integer> list) { this.list = list; } public List<Integer> getList() { return list; } public void setList(List<Integer> list) { this.list = list; } @Override protected Object clone() throws CloneNotSupportedException { try{ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); Person clone = (Person)ois.readObject(); return clone; }catch (Exception e){ e.printStackTrace(); return null; }}}Copy the code

The test class

List<Integer> list =new ArrayList<>(); list.add(1); list.add(2); Person person =new Person(list); Person clone = (Person)person.clone(); System.out.println(person.getList()== Clone.getList()); Println ("cloneList= "+ cloneList=" + Cloner.getList ())); list.add(3); person.setList(list); System.out.println("cloneList= "+ cloneList. GetList ()); System.out.println("person = " + person.getList());Copy the code

The results of

CloneList = [1, 1] cloneList= [1, 2] cloneList= [1, 2] Person = [1, 2, 3] // Person = [1, 2, 3Copy the code

The prototype pattern

Prototype patterns are used to create duplicate objects while ensuring performance, and are based on deep copy patterns. This type of design pattern is a creation pattern and is one of GOF’s design patterns, which provides an optimal way to create objects.

Prototype pattern usage scenarios

The purpose of the prototype pattern is to reduce the number of instance objects and reduce the number of constructor calls.

  • Too many resources are required for class initialization: If too many resources are consumed during class initialization and a large amount of memory is occupied, in order to save overhead;
  • Cumbersome and time-consuming initialization: The creation of class objects requires a lot of computation or frequent interaction with local resources (databases and files). Each creation consumes a lot of CPU and time resources.
  • Complex constructors: The constructors defined in the class are complex, for example, there are dozens or hundreds of member attributes;
  • Large number of instance objects: If you loop through memory to create a large number of instance objects, you can use the prototype pattern to reuse unused objects to create new objects.

Steps to implement the prototype pattern in Java

1. The prototype implements the Cloneable interface

2. Both prototype objects and their member objects implement the Serializable interface

3. Rewrite the Clone () method to serialize the data stream for deep copy.

The use of prototype patterns in Spring

The classic framework Spring also uses the prototype pattern,scope=”prototype”, through which beans are acquired by multi-instance objects

If (mbD.issingleton ()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName,); mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; }}); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbD.isprototype ()) {// It's a prototype -> create a new instance. Object prototypeInstance = null; Try {// make callbacks before creating prototypes beforePrototypeCreation(beanName); PrototypeInstance = createBean(beanName, MBD, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); }Copy the code

Thank you for watching!