Prototype patterns of Java design patterns

Source: Internet
Author: User
Tags shallow copy

Introduction to prototype mode

Prototype mode is not really a design pattern, it should be a trick. When we need to create objects that are the same as existing objects, we can usually have two easy-to-think methods, one of which is to point an existing object to another re-created object, such as

Assign old to NewObject Newobject=oldobject;



This approach is equivalent to newobject or to the address of the oldobject, that is, the two are actually the same, the future is the same, arbitrarily on which object to make changes, both will be consistent, because they can be regarded as two the same "pointer"; Another common practice is that Recreate an object, instantiate it with new, and create another object that writes an object to memory, although the content is the same but the address is different, but this is laborious, if the object is more complex.

Prototype mode is born under this requirement, we know that object is the parent of all objects (superclass), and object has a native clone method, but the invocation of the method must require the class to implement the Cloneable interface, although the Cloneable interface is just a device, It's empty, just let it be. Cloneable interface is a symbol of the implementation of the Clone Method! We can create a class to implement cloneable, and then overwrite the Clone method to complete the clone of the class.

code implementation of the prototype pattern

The following is a dog class, the class implements the Cloneable interface, and overwrite the superclass of the Clone method, which uses the Super.clone, which means calling the superclass's native code. Note that the dog class has a variable eye with a non-basic data type, and this point is described below.

Shallow copy
Package Com.prototype;import Java.io.bytearrayinputstream;import Java.io.bytearrayoutputstream;import Java.io.ioexception;import Java.io.objectinputstream;import Java.io.objectoutputstream;import Java.io.serializable;public class Dog implements cloneable,serializable {/** *  */private static final long Serialversionuid = -2050795770781171788l;private String name; Eye Eye;public Dog (eye eye) {This.eye=eye;} Public String GetName () {return name;} public void SetName (String name) {this.name=name;} @Overrideprotected Object Clone () throws Clonenotsupportedexception {dog dog;dog= (dog) Super.clone (); return Dog;}    } Class Eye Implements serializable{/** *  */private static final long serialversionuid = -2723012171722328322l; String Name;public Eye (string name) {This.name=name;}}



replication Methods in prototype mode

in the prototype pattern code above, we override the Clone method, let's take a test:

test Code One:

Package com.prototype;/** * @author ZZW922CN * */public class Test1 {public static void main (string[] args) throws Cloneno tsupportedexception {Dog dog = new Dog (new Eye ("Red Eyes"));d og.setname ("Dogs One");D og object1 = (dog) dog.clone (); O Bject1.eye.name= "green Eyes"; Object1.setname ("Dog II"); System.out.println (Dog.eye.name); System.out.println (Object1.eye.name); System.out.println (Dog.getname ()); System.out.println (Object1.getname ()); System.out.println (Object1.equals (dog)); System.out.println (Object1==dog); System.out.println (Object1.getclass (). Equals (Dog.getclass ()));}}



As you can see in the above code, OBJECT1 is the clone of dog, what happens when we make the clone, then call the relevant settings for Object1, change the variable of the eye type and the variable of type string? Will dog change? and is object1 the same as dog (equals and = =)? Do they belong to the same class? The last question is unquestionable, certainly the same class.

Run results

Green eyes green eyes dog a dog two falsefalsetrue



As you can see from the results of the run, the name of the dog's eye object is automatically changed from red to green when Object1 modifies the eye object, but when Object1 modifies the name object of type string, dog retains its original name object. Is there any connection or difference between the two? Links are both string and eye are non-basic data types, and Java's eight basic data types are char,byte,int,short,long,float,double,boolean. The difference is that since the same is a non-basic data type, but one follows the clone object changes and the other one remains the same, it is very strange. Because it is a string type, string is an exception. So, to summarize the Clone method, we know that the basic data type field of the cloned object is the copy of the original Object field, but the non-primitive type (except string) is not copied, but rather a reference to the primitive type of the original object. This is just like the relationship between NewObject and Oldobject at the beginning of the blog post. The string type is an exception, which is a copy of the original object, not the address of the original string object.

This clone is generally called shallow copy, which is not completely copied!

Test Code Two

The following is a deep copy, which is full replication. I use streams to make deep copies, that is, full copies.

Deep copy
Package Com.prototype;import Java.io.bytearrayinputstream;import Java.io.bytearrayoutputstream;import Java.io.ioexception;import Java.io.objectinputstream;import Java.io.objectoutputstream;import Java.io.serializable;public class Dog implements cloneable,serializable {/** * */private static final long Serialversionu ID = -2050795770781171788l;private String name; Eye Eye;public Dog (eye eye) {This.eye=eye;} Public String GetName () {return name;} public void SetName (String name) {this.name=name;} @Overrideprotected Object Clone () throws Clonenotsupportedexception {dog dog;dog= (dog) Super.clone (); return Dog;          /* Deep Copy */public Object Deepclone () throws IOException, ClassNotFoundException {/* Write binary stream of current object */          Bytearrayoutputstream BOS = new Bytearrayoutputstream ();          ObjectOutputStream oos = new ObjectOutputStream (BOS);            Oos.writeobject (this);     /* read out the new object generated by the binary stream */Bytearrayinputstream bis = new Bytearrayinputstream (Bos.tobytearray ());     ObjectInputStream ois = new ObjectInputStream (bis);      return Ois.readobject (); }}class Eye Implements serializable{/** * */private static final long serialversionuid = -2723012171722328322l; String Name;public Eye (string name) {This.name=name;}}



And then write a similar test code

Package Com.prototype;import Java.io.ioexception;public class Test2 {/** * equal emphasize whether the content is the same * = emphasize whether the address is the same * @param args * @thro WS clonenotsupportedexception * @throws ioexception  * @throws classnotfoundexception  */public static void Main ( String[] args) throws Clonenotsupportedexception, ClassNotFoundException, IOException {dog dog = new Dog (new Eye ("Red Eyes")); Dog.setname ("dog One"); System.out.println ("-----------------deep copy--------------");D og object2 = (Dog) dog.deepclone (); Object2.eye.name= "Green eyes "; Object2.setname (" Dog II "); System.out.println (Dog.eye.name); System.out.println (Object2.eye.name); System.out.println (Dog.getname ()); System.out.println (Object2.getname ()); System.out.println (Object2.equals (dog)); System.out.println (Object2==dog); System.out.println (Object2.getclass (). Equals (Dog.getclass ()));}}



To run the test results:
-----------------deep copy--------------red eyes green eyes dog a dog two falsefalsetrue



When we see deep replication, the two "go our separate ways", except for the same thing as the beginning of replication, and any subsequent changes will have no effect on each other. This is the deep copy. the difference between equals and = =

Earlier we saw that both the Clone object and the equals and = = of the original object return false, whether it is a shallow copy or a deep copy. So what is the relationship between equals and = =?

For basic data types, = = compares their values. For non-primitive types of objects, = = comparison is their address in memory, such as the previous oldobject and newobject the same address, while the Equals method, if it does not overwrite the quilt class, it is also the most primitive comparison object in memory address, if the quilt class overwrite, It's hard to say. For example, in the string type, the Equals method compares the "surface value" of the string, which is not the address of the object in memory, and = = compares whether the two string addresses in memory are the same. For example, string str1= "Java", String Str2=new string ("Java"), then the relationship between the two is Str1!=str2,str1.equals (STR2) =true. The reason is that str1 exists in the string constant pool, str2 exists in the Java heap, and the addresses are of course different, but the surface values are the same, both Java, so the Equals method returns True.

Prototype patterns of Java design patterns

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.