An in depth understanding of the copy mechanism in java

  • 2020-06-07 04:32:27
  • OfStack

preface

It is well known that in Java, there are two types of copy: deep copy and shallow copy. java implements a method called clone in the common superclass Object, which produces a shallow copy of the new object and a deep copy of the self-defined clone method.

(1) clone method in Object

If new issues a new object, references it with one declaration, and then references the previous declaration with another declaration, the end result is that both declared variables will point to the same object, and all of them will be changed at one place. If we want to create an copy of an object, which has the same attributes as the object, and modify the copy that has nothing to do with the original object, we use the clone method.


package Clone;

import java.util.Date;

/**
 * 
 * @author QuinnNorris 
 * java Two copy mechanisms 
 */
public class Clone {

 /**
 * @param args
 * @throws CloneNotSupportedException 
 */
 public static void main(String[] args) throws CloneNotSupportedException {
 // TODO Auto-generated method stub

 ClassA valA = new ClassA(1, "old", new Date());
 //  The statement 1 A new one ClassA Objects, we don't need to pay too much attention ClassA The function of the 
 ClassA valB = valA;
 //  will valA Object assigned to valB
 valA.setObject("new");
 //  To change the valA Is the value of valB It has also been changed because valA and valB Point to the same 1 An object 

 valB = valA.clone();// through clone Method copy making 
 }
}

The clone method overrides in the ClassA class:


// You need to implement Cloneable interface 
public class ClassA implements Cloneable {

 public ClassA clone() throws CloneNotSupportedException {
 return (ClassA) super.clone();// Calling the parent class ( Object ) clone methods 
 }

}

1. How to use clone method in Object

Someone has summarized 4 rules for using the clone method. Let's start with 1 and share 1:

To get a copy of the object, we can take advantage of the clone() Methods. Overriding the base class in a derived class clone() Method and declare as public. In derived classes clone() Method, call super.clone() Implement the Cloneable interface in a derived class.

2. clone method modified by protected

In java. lang. Object, he sets the clone method to protected modification, which is a very special case. The scope of protected is: package visibility + inheritance. The reason for this setting is that what this method should return is the cloned object, that is, the type of clone method should be cloned is unknown, and there is no way to determine the type of the return value. Naturally, it can only be overridden by descendants to achieve it. In order to make descendants inherit but still open, it is set as protected type.

3. Implementing the clone method requires implementing the Cloneable interface

So why did we implement the Cloneable interface when we overwrote the clone method? In fact, THE Cloneable interface is one of the tag interfaces in java. The tag interface refers to those interfaces that have no methods or properties. They exist only to let people know some information and can be judged when using xxx instanceof Cloneable. The interface Cloneable was created to let designers know about cloning. If an object needs to be cloned but does not implement the Cloneable interface (in fact, writing instead of implementing is more accurate here), a checked exception will be generated.

4. Implementing the clone method requires calling clone, the parent class

We need to use the parent clone method in order to copy 1 object and call the object 1 modular object of the method, the parent class and so on, until clone method of Object is reached, so what is the use of clone method of Object? API says:

protected Object clone( ) throws CloneNotSupportedException

Creates and returns a copy of this object.

The exact meaning of "copy" may depend on the class of the object. The idea is that for any object, x,

Expressions: x.clone() != x为 true .

Expressions: x.clone().getClass() == x.getClass()也为 true .

But these are not requirements that must be met.

1. In general:

x.clone().equals(x) true, but it is not a requirement that must be met.

By convention, the returned object should be called super.clone To obtain.

If 1 class and all its superclasses (except Object) comply with this convention x.clone().getClass() == x.getClass()

Above is the basic explanation of PART 1 of clone. We can come to the conclusion that as long as the call is reasonable clone()0 It returns a cloned object. At runtime, in Object clone() Identify which object you want to copy, then allocate space for that object, copy the object, copy the contents of the original object 11 to the storage space of the new object. In the cloned object, all attributes are the same as those of the cloned object, and these attributes are divided into two types:

Type 1:8 large primitive types and immutable objects (such as String)

Type 2: Other class objects

For the first, the clone method sets their value to the value of the original object without any problem. For the second, the clone method simply points the reference of the copied new object to the reference of the original object, and the second class object is modified by both objects. This is where the concept of a shallow copy comes in.

(2) Shallow copy

Shallow copy: All variables of the copied object have the same value as the original object, while all references to other objects still point to the original object. In other words, shallow replication simply copies the object in question, not the object it references.

For example, one class A has another class B type variable. When A overrides the clone function call to ES149en.clone, the new object is created with the same type variable of class B in the original object, pointing to the same type variable of B. If the variable of B is modified in A, the variable of B will be modified in the new copied object.

Remember that the clone methods that call the super.clone implementation directly are all shallow copies.

(3) Deep copy

Deep copy: All variables of the copied object have the same value as the original object, except those that reference other objects. Variables that refer to other objects will point to new objects that have been copied, instead of the original referenced objects. In other words, deep copy copies all objects referenced by the object to be copied once.

In layman's terms, if a shallow copy starts with two lines, then if there is a variable of another class at the end, then the two lines eventually combine 2 to 1, pointing to the variable together, and both can operate on it. The deep copy is completely two lines and does not interfere with each other, because it has copied all the internal variable objects once.

Deep copy in the code requires more clone functions in the clone method that call variables from other classes in the class.

(4) Serialized deep copy

In the framework, we sometimes find that the clone method is not overridden, so how do we operate when we need to copy an object? The answer is that we often implement the Serializable interface using serialization methods.

There is no other way to replace the deep copy. If you use the traditional deep copy, do you copy an object by chasing down numerous layers to copy all the object variables? Regardless of the time it takes to do so, just writing such code is daunting. Serializing deep copy is such a relatively simple method.

The process of writing objects to the stream is a serialization (Serilization) process, but in Java programmer circles it is very well known as the "freeze" or "pickle (picking)" process. The parallelization (Deserialization) process of reading an object from a stream is called a "thaw" or "recycle" process. It should be noted that what is written in the stream is a copy of the object, and the original object still exists in JVM, so what is "salted" is only a copy of the object, and Java is still fresh.

It's a professional explanation on the Internet, and I'm not here to teach fish to swim. In THE Java language, it is often possible to make an object implement the Serializable interface, then write the object (which is really just a copy of the object) into a stream (salted as pickles) and read it out of the stream (fresh pickles) to recreate the object.


public Object deepClone() 
{ 
 // Written to the object  
 ByteArrayOutoutStream bo=new ByteArrayOutputStream(); 
 ObjectOutputStream oo=new ObjectOutputStream(bo); 
 oo.writeObject(this); 
 // Read the object 
 ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); 
 ObjectInputStream oi=new ObjectInputStream(bi); 
 return(oi.readObject()); 
}

Although this academic code looks complicated, it's really just a matter of putting objects in the stream and taking them out. Compared to the countless clone analyses, this is simply too simple. This assumes that the object and all objects referenced within the object are serializable; otherwise, you need to carefully examine whether non-serializable objects are set to transient.

transient: an object as long as to achieve the Serilizable interface, this object can be serialized (serialization refers to the java code written in the form of a sequence of bytes, namely we code above 3 lines written to the object), the serialization of Java model for developers to provide a lot of convenience, can need not relationship between specific serialization process, as long as the class implements the Serilizable interface, this all of the attributes and methods automatically serialized. But there's a situation where some properties don't require a serial number, so that's where the keyword comes in. Simply implement the Serilizable interface and add the keyword transient before the property that does not need to be serialized. When serializing the object, the property will not be serialized to the specified destination.

conclusion

In practical applications, deep copy and shallow copy are just two concepts. It is not clear who is better than whom. It is necessary to determine how to copy an object according to the actual work. In the case of database operations, a shallow copy is definitely required in order to fetch one table without involving other tables, and in the case of Serializable of the framework, a deep copy is necessary, although time-consuming.

The above is the whole content of this article, I hope the content of this article can bring 1 definite help to your study or work, if you have any questions, you can leave a message to communicate.


Related articles: