zoukankan      html  css  js  c++  java
  • 浅拷贝与深拷贝的实现

    需要实现对某个对象的拷贝,做了个小例子,便于日后复习。需要拷贝的对象属于Student类型,包含两个字段sex和userName,而userName是属于引用类型。对应的类是Name,该类包含firstName和lastName。代码如下:

       class Name {

           private String firstName ="";

           private String lastName = "";

     

           public void setLastName(String lastName) {

               this.lastName = lastName;

           }

           public String getLastName() {

               return lastName;

           }

           public void setFirstName(String firstName) {

               this.firstName = firstName;

           }

           public String getFirstName() {

               return firstName;

           }

        }

       public class Student {

           private String sex = "";

           private Name userName = null;

     

           public void setUserName(Name userName) {

               this.userName = userName;

           }

           public Name getUserName() {

               return userName;

           }

           public void setSex(String sex) {

               this.sex = sex;

           }

           public String getSex() {

               return sex;

           }

       }

    当在main方法中写如下代码:

      public static void main(String[] args) throws Exception {

    Name name = new Name();

           name.setFirstName("Zhang");

           name.setLastName("San");   

    Student student1 = new Student();

           student1.setSex("");

           student1.setUserName(name);

      }

    当执行完student1的赋值后,存储的情况大致如下:

     

    需要一个Student类型的对象student2,并且student2从student1复制而来,涉及到两种复制模式,

    一是浅拷贝:即将student1的所有的成员变量的值拷贝给student2,但是对于引用类型则是拷贝的地址引用,所有完成浅拷贝后student2与student1中的引用类型的变量userName还是指的同一个对象,当student1的成员变量userName中firstName的值发生改变时,student2的userName中的firstName也会受到影响。浅拷贝后内存中的存储大致如下:

    由图容易看出student1与student2对象的userName属性对应的是同一个对象,所有当userName对象中的firstName或是lastName发生改变时,两个对象的对于的属性的值都会受到影响。

    第二种拷贝为深拷贝,即对象中的引用类型的变量的值也做拷贝,拷贝后不指向同一对象,这样的话成员变量值的改变互相不会受影响,深拷贝后的内存存储大致如下:

    明白了深拷贝与浅拷贝的不同之处后,我们来分别实现两种不同的拷贝。

    1,对于浅拷贝可以通过Object对象的clone方法实现。需要被拷贝的对象要实现Cloneable接口,实现clone方法,对应我们的Student类只需要做一些修改即可。public class Student implements Cloneable {

           private String sex = "";

           private Name userName = null;

     

           public void setUserName(Name userName) {

               this.userName = userName;

           }

           public Name getUserName() {

               return userName;

           }

           public void setSex(String sex) {

               this.sex = sex;

           }

           public String getSex() {

               return sex;

           }

          

           @Override

           protected Object clone() throws CloneNotSupportedException {

               return super.clone();

           }

    }

     生成studnet1对象后,只需要使用以下语句即可复制生成student2对象:

     Student student2 = (Student)student1.clone();

    如果借助apache的beanutils还可以通过以下方式实现浅拷贝

    Student student2 = (Student)BeanUtils.cloneBean(student1);

    2,对应深拷贝则需要通过序列化的方式实现

    public class Student implements Cloneable,Serializable {

           private static final long serialVersionUID = 5932252818552269951L;

           private String sex = "";

           private Name userName = null;

           public void setUserName(Name userName) {

               this.userName = userName;

           }

           public Name getUserName() {

               return userName;

           }

           public void setSex(String sex) {

               this.sex = sex;

           }

           public String getSex() {

               return sex;

           }

          

           @Override

           protected Object clone() throws CloneNotSupportedException {

               return super.clone();

           }

          

           public Student deepClone() throws Exception {

               Student s = null;

               ByteArrayOutputStream baos = new ByteArrayOutputStream();

               ObjectOutputStream oos = new ObjectOutputStream(baos);

               oos.writeObject(this);

               oos.flush();

               oos.close();

              

               byte[] arrByte = baos.toByteArray();

               ByteArrayInputStream bais = new ByteArrayInputStream(arrByte);

               ObjectInputStream ois = new ObjectInputStream(bais);

               s = (Student)ois.readObject();

               ois.close();

               return s;

           }

        }

    调用deepClone方法就可以实现深拷贝。

    Student student2 = student1.deepClone();

    可以根据实际的需要选择浅拷贝或是深拷贝。

  • 相关阅读:
    配置linux 防火墙,只有固定IP和端口才能能访问完美解决
    转.HTML中img标签的src属性绝对路径问题解决办法,完全解决!
    weblogic 安全漏洞问题解决
    转 echarts 的使用时遇到的坑 初始化和销毁,亲测有效!
    在使用 Fortify进行源码扫描时需要做对项目需要做什么?
    eclipse 导出 jar包详细步骤
    转 Fortofy扫描漏洞解决方案2
    JSON 之 SuperObject(1)
    Delphi使用JSON解析调用淘宝IP地址库REST API 示例
    Jsoncpp的使用
  • 原文地址:https://www.cnblogs.com/gmq/p/1747435.html
Copyright © 2011-2022 走看看