Home > Java > javaTutorial > Java Improvement Part 5 -----Using Serialization to Copy Objects

Java Improvement Part 5 -----Using Serialization to Copy Objects

黄舟
Release: 2017-02-09 13:39:07
Original
1175 people have browsed it

We know that this interface Cloneable exists in Java. Classes that implement this interface will have the ability to be copied. At the same time, copying is performed in memory. In terms of performance, it is faster than directly generating objects through new, especially in In the generation of large objects, the performance improvement is very obvious. However, we know that copy is divided into deep copy and shallow copy, but shallow copy has the problem of incomplete copy of object attributes. Regarding deep copy and shallow copy, please refer here: Gradual analysis of shallow copy and deep copy of java

1. Shallow copy problem

Let’s first look at the following code:

public class Person implements Cloneable{  
    /** 姓名 **/  
    private String name;  
      
    /** 电子邮件 **/  
    private Email email;  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public Email getEmail() {  
        return email;  
    }  
  
    public void setEmail(Email email) {  
        this.email = email;  
    }  
      
    public Person(String name,Email email){  
        this.name  = name;  
        this.email = email;  
    }  
      
    public Person(String name){  
        this.name = name;  
    }  
  
    protected Person clone() {  
        Person person = null;  
        try {  
            person = (Person) super.clone();  
        } catch (CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
          
        return person;  
    }  
}  
  
public class Client {  
    public static void main(String[] args) {  
        //写封邮件  
        Email email = new Email("请参加会议","请与今天12:30到二会议室参加会议...");  
          
        Person person1 =  new Person("张三",email);  
          
        Person person2 =  person1.clone();  
        person2.setName("李四");  
        Person person3 =  person1.clone();  
        person3.setName("王五");  
          
        System.out.println(person1.getName() + "的邮件内容是:" + person1.getEmail().getContent());  
        System.out.println(person2.getName() + "的邮件内容是:" + person2.getEmail().getContent());  
        System.out.println(person3.getName() + "的邮件内容是:" + person3.getEmail().getContent());  
    }  
}  
--------------------  
Output:  
张三的邮件内容是:请与今天12:30到二会议室参加会议...  
李四的邮件内容是:请与今天12:30到二会议室参加会议...  
王五的邮件内容是:请与今天12:30到二会议室参加会议...
Copy after login

In this application, first define an email, and then send the email to Zhang San, Li Si, and Wang Wu. Since they use the same email and only have different names, they use Zhang San’s object class Just copy the John Four and King Five objects and change the names. There is nothing wrong with the program until here, but if we need Zhang San to arrive 30 minutes in advance, we will modify the content of the email:

public class Client {  
    public static void main(String[] args) {  
        //写封邮件  
        Email email = new Email("请参加会议","请与今天12:30到二会议室参加会议...");  
          
        Person person1 =  new Person("张三",email);  
          
        Person person2 =  person1.clone();  
        person2.setName("李四");  
        Person person3 =  person1.clone();  
        person3.setName("王五");  
          
        person1.getEmail().setContent("请与今天12:00到二会议室参加会议...");  
          
        System.out.println(person1.getName() + "的邮件内容是:" + person1.getEmail().getContent());  
        System.out.println(person2.getName() + "的邮件内容是:" + person2.getEmail().getContent());  
        System.out.println(person3.getName() + "的邮件内容是:" + person3.getEmail().getContent());  
    }  
}
Copy after login

Here we also use the object of Zhang San to realize the processing of Li Si and Wang Wu Copy, and finally change the content of Zhang San's email to: Please come to the second conference room at 12:00 today to attend the meeting... But the result is:

张三的邮件内容是:请与今天12:00到二会议室参加会议...  
李四的邮件内容是:请与今天12:00到二会议室参加会议...  
王五的邮件内容是:请与今天12:00到二会议室参加会议...
Copy after login

Here we wonder why the content of Li Si and Wang Wu's emails was also changed? There will be objections if they are asked to arrive 30 minutes early!

In fact, the key to the problem lies in the clone() method. We know that the clone() method uses the clone() method of the Object class, but this method has a flaw. It does not copy the object's All attributes are copied, but copied selectively. The basic rules are as follows:

1. Basic type

If the variable is a basic type, copy its value, such as int, float wait.

2. Object

If the variable is an instance object, copy its address reference, which means that the new object and the original object share the instance variable at this time.

3. String string

If the variable is a String string, copy its address reference. But when modified, it will regenerate a new string from the string pool, and the original Ziducheng object remains unchanged.

Based on the above rules, we can easily find the problem. The three of them share a common object. If Zhang San modifies the content of the email, Li Si and Wang Wu will also modify it, so the above appears. Case. We can still solve this situation. We only need to create a new object in the clone() method, and then Zhang San references the object:

protected Person clone() {  
        Person person = null;  
        try {  
            person = (Person) super.clone();  
            person.setEmail(new Email(person.getEmail().getObject(),person.getEmail().getContent()));  
        } catch (CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
          
        return person;  
    }
Copy after login

So: Shallow copy is just a simple method provided by Java. The copy mechanism is not easy to use directly.

There is still a problem with the above solution. If there are a large number of objects in our system that are generated by copying, if we write a clone() method for each class, deep copies will also be required. , create a large number of new objects, this project is very large, here we can use serialization to copy the objects.

2. Use serialization to copy objects

How to use serialization to copy objects? It is relatively easy to achieve by copying the byte stream in memory. Write the parent object into a byte stream, and then read it out from the byte stream, so that you can create a new object, and there is no problem of reference sharing between the new object and the parent object. Really implement deep copy of objects.

public class CloneUtils {  
    @SuppressWarnings("unchecked")  
    public static <T extends Serializable> T clone(T obj){  
        T cloneObj = null;  
        try {  
            //写入字节流  
            ByteArrayOutputStream out = new ByteArrayOutputStream();  
            ObjectOutputStream obs = new ObjectOutputStream(out);  
            obs.writeObject(obj);  
            obs.close();  
              
            //分配内存,写入原始对象,生成新对象  
            ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());  
            ObjectInputStream ois = new ObjectInputStream(ios);  
            //返回生成的新对象  
            cloneObj = (T) ois.readObject();  
            ois.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return cloneObj;  
    }  
}
Copy after login

Objects using this tool class must implement the Serializable interface, otherwise there is no way to achieve cloning.

public class Person implements Serializable{  
    private static final long serialVersionUID = 2631590509760908280L;  
  
    ..................  
    //去除clone()方法  
  
}  
  
public class Email implements Serializable{  
    private static final long serialVersionUID = 1267293988171991494L;  
      
    ....................  
}
Copy after login

Therefore, objects using this tool class can achieve object cloning as long as they implement the Serializable interface, and there is no need to inherit the Cloneable interface to implement the clone() method.

public class Client {  
    public static void main(String[] args) {  
        //写封邮件  
        Email email = new Email("请参加会议","请与今天12:30到二会议室参加会议...");  
          
        Person person1 =  new Person("张三",email);  
          
        Person person2 =  CloneUtils.clone(person1);  
        person2.setName("李四");  
        Person person3 =  CloneUtils.clone(person1);  
        person3.setName("王五");  
        person1.getEmail().setContent("请与今天12:00到二会议室参加会议...");  
          
        System.out.println(person1.getName() + "的邮件内容是:" + person1.getEmail().getContent());  
        System.out.println(person2.getName() + "的邮件内容是:" + person2.getEmail().getContent());  
        System.out.println(person3.getName() + "的邮件内容是:" + person3.getEmail().getContent());  
    }  
}  
-------------------  
Output:  
张三的邮件内容是:请与今天12:00到二会议室参加会议...  
李四的邮件内容是:请与今天12:30到二会议室参加会议...  
王五的邮件内容是:请与今天12:30到二会议室参加会议...
Copy after login

The above is the content of Java Improvement Part 5-----Using Serialization to Copy Objects. For more related content, please pay attention to the PHP Chinese website (m.sbmmt.com)!


source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template