In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the relevant knowledge of "what is the deep and shallow copy of Java". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Reference copy
The reference copy generates a new object reference address, but the two final points are still the same object. How to better understand the citation copy? Very simply, take us, for example, we usually have a name, but different occasions and characters may call us differently, but we know very well which names belong to "me"!
Of course, let's take a look at a code example (don't write get, set, etc., for simplicity):
Class Son {String name; int age; public Son (String name, int age) {this.name = name; this.age = age;}} public class test {public static void main (String [] args) {Son S1 = new Son ("son1", 12); Son S2 = S1; s1.age = 22; System.out.println (S1) System.out.println (S2); System.out.println ("S1 age:" + s1.age); System.out.println ("S2 age:" + s2.age); System.out.println ("s1==s2" + (s1==s2)); / / equivalent}}
The result of the output is:
Age:22 true of age:22 S2 of Son@135fbaa4 Son@135fbaa4 S1
Shallow copy
How do you create an object that copies the contents of the target object instead of copying the reference directly?
Here we first talk about the shallow copy, which creates a new object. There is no relationship between the new object and the original object. The new object is different from the original object, but the properties of the new object are the same as those of the old object. Specifically, you can see the following differences:
If the attribute is a base type (int,double,long,boolean, etc.), the value of the base type is copied
If the property is a reference type, the memory address is copied (that is, objects that copy references but not references), so if one object changes this address, the other object is affected.
If you use a picture to describe a shallow copy, it should look like this:
How to achieve shallow copy? It is also simple to implement the Cloneable interface on the class that needs to be copied and override its clone () method.
@ Override protected Object clone () throws CloneNotSupportedException {return super.clone ();}
Just call the clone () method of the class directly when you use it. Specific examples are as follows:
Class Father {String name; public Father (String name) {this.name=name;} @ Override public String toString () {return "Father {" + "name='" + name +'\'+'}';} class Son implements Cloneable {int age; String name; Father father Public Son (String name,int age) {this.age=age; this.name = name;} public Son (String name,int age, Father father) {this.age=age; this.name = name; this.father = father } @ Override public String toString () {return "Son {" + "age=" + age + ", name='" + name +'\'+ ", father=" + father +'}';} @ Override protected Son clone () throws CloneNotSupportedException {return (Son) super.clone () }} public class test {public static void main (String [] args) throws CloneNotSupportedException {Father f=new Father ("bigFather"); Son S1 = new Son ("son1", 13); s1.fatherdistribuf; Son S2 = s1.clone (); System.out.println (S1); System.out.println (S2); System.out.println ("s1==s2:" + (s1==s2)) / / unequal System.out.println ("s1.name==s2.name:" + (s1.name==s2.name)); / / equivalent System.out.println (); / / but their Father father and String name references are the same s1.ageq12; s1.father.name = "smallFather"; / / s1.father references remain unchanged s1.name = "son222" / / similar s1.name=new String ("son222") references change System.out.println ("s1.Father==s2.Father:" + (s1.father = = s2.father)); / / equivalent System.out.println ("s1.name==s2.name:" + (s1.name==s2.name)); / / unequal System.out.println (S1); System.out.println (S2);}}
The running result is:
Son {age=13, name='son1', father=Father {name='bigFather'}} Son {age=13, name='son1', father=Father {name='bigFather'}} s1==s2:false s1.name==s2.name:true// now equal s1.Father==s2.Father:true s1.name==s2.name:false// modified reference unequal Son {age=12, name='son222', father=Father {name='smallFather'}} Son {age=13, name='son1', father=Father {name='smallFather'}}
Not surprisingly, except for the object itself, all the parts and relationships and copy objects are the same, just like twins, two people, but the appearance of the beginning, all kinds of relationships (parents and relatives) are the same. Note that where name initial = = is equal, because the initial shallow copies point to the same String, and then s1.name = "son222" changes the reference point.
Deep copy
For the above question, although the two objects copied are different, but some of the internal references are still the same, how to copy this object absolutely so that it is completely independent of the original object? Use our deep copy. Deep copy: when you copy the reference data type, a new object is created and the member variables in it are copied.
In the implementation of deep copy, there are two ways to rewrite the clone () method and the sequence method.
Override the clone () method
If you use the override clone () method to implement a deep copy, you will also implement the Cloneable interface to implement the clone () method for all classes in the class that have custom reference variables. For character classes, you can create a new string implementation copy.
For the above code, the Father class implements the Cloneable interface and overrides the clone () method. The clone () method of son needs to copy each reference.
/ / Father clone () method @ Override protected Father clone () throws CloneNotSupportedException {return (Father) super.clone ();} / / Son clone () method @ Override protected Son clone () throws CloneNotSupportedException {Son son= (Son) super.clone (); / / object to be copied son.name=new String (name); son.father=father.clone (); return son;}
The other code remains the same, and the execution result is as follows:
Son {age=13, name='son1', father=Father {name='bigFather'}} Son {age=13, name='son1', father=Father {name='bigFather'}} s1==s2:false s1.name==s2.name:false s1.Father==s2.Father:false s1.name==s2.name:false Son {age=12, name='son222', father=Father {name='smallFather'}} Son {age=13, name='son1', father=Father {name='bigFather'}}
Serialization
You can find that deep copy is achieved in this way. But there is a problem with this situation. What if there are too many references or layers?
It's impossible to write clone () one by one for each object, is it? What are we going to do? With serialization.
Because after serialization: the content of the binary byte stream is written to a medium (text or byte array), and then the data is read from this medium, and the original object is written to this medium and copied to the clone object, the modification of the original object does not affect the clone object, because the clone object is read from this medium.
People familiar with object caching know that we often cache Java objects into Redis, and then possibly read and generate Java objects from Redis, which uses serialization and deserialization. Generally, Java objects can be stored as byte streams or json strings and then deserialized into Java objects. Because serialization stores the properties of the object, it does not and cannot store information about the address of the object in memory. So all reference objects are recreated when deserialized to Java objects.
In the concrete implementation, the custom class needs to implement the Serializable interface. Define a function in the class (Son) that requires a deep copy to return the class object:
Protected Son deepClone () throws IOException, ClassNotFoundException {Son son=null; / / create a byte array buffer in memory, and all data sent to the output stream is saved in the byte array / / create a buffer ByteArrayOutputStream byOut=new ByteArrayOutputStream () of size 32 by default; / / serialize output ObjectOutputStream outputStream=new ObjectOutputStream (byOut) of the object / / transfer outputStream.writeObject (this) as a byte array; / / write the current student object to the byte array / / create a byte array buffer in memory, and save the data read from the input stream in the byte array buffer ByteArrayInputStream byIn=new ByteArrayInputStream (byOut.toByteArray ()); / / receive the byte array as a parameter to create ObjectInputStream inputStream=new ObjectInputStream (byIn) Son= (Son) inputStream.readObject (); / / read return son; from byte array}
When you use it, you can call the method we wrote. Other things remain the same. The results are as follows:
Son {age=13, name='son1', father=Father {name='bigFather'}} Son {age=13, name='son1', father=Father {name='bigFather'}} s1==s2:false s1.name==s2.name:false s1.Father==s2.Father:false s1.name==s2.name:false Son {age=12, name='son222', father=Father {name='smallFather'}} Son {age=13, name='son1', father=Father {name='bigFather'}} "what is the deep and shallow copy of Java", thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.