浅克隆和深克隆

为什么要使用克隆

         在业务中,有时候需要对对象进行克隆。例如Student对象,如果如下代码进行“克隆”,其实是引用重新赋值

     Student stu1 = new Student();
     stu1.setName("测试1");
     stu1.setAge(23);
     Student stu2 = stu1;
  

      在上述代码中如果,对stu1,或者stu2的属性进行改变,两者的属性都会发生相同的改变。这样赋值,堆中还是只用一个Student对象,只不过在栈中存在stu1,stu2两个引用指向堆中的Student对象。

浅克隆

     针对对象中的属性没有引用类型,都是基本数据类型。例如如下代码:

  1.首先创建Student对象

            创建Student对象,其中的属性是String类型的name,int类型的age。克隆需要继承Cloneable接口,这个接口是标识性接口。然后重写object中的clone方法。

package com.wx.qianKeLong;

public class Student implements Cloneable{
    private String  name;
    private int age;

    //private Address address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

//    public Address getAddress() {
//        return address;
//    }
//
//    public void setAddress(Address address) {
//        this.address = address;
//    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Student student = null;
        student = (Student) super.clone();
       // student.address = (Address) address.clone();
        return student;
    }


    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
               // ", address=" + address +
                '}';
    }
}

  2.创建测试类

    在该类中,创建student对象,然后对student中的属性中name设置为wx,age设置为24。然后对student对象进行克隆,克隆后的对象为student1,然后student1对属性进行改变,name为wx2,age为25.最后将student的引用赋值给student3,student3对属性name和age进行修改

package com.wx.qianKeLong;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        //Address address= new Address();
        //address.setName("China");
        student.setName("wx");
        student.setAge(24);
        System.out.println("未修改之前的Student:"+student);
        //student.setAddress(address);
        Student student1 = (Student) student.clone();
        //address.setName("American");
        student1.setName("wx2");
        student1.setAge(25);
        Student student2 = student;
        student2.setName("wx3");
        student2.setAge(16);
        System.out.println(student);
        System.out.println(student1);
        System.out.println(student2);
        System.out.println("===============================");
    }
}

结果

                                           

通过结果说明,student1通过克隆产生了新的对象,而student2只是引用的复制,当student2对属性进行修改,student的属性也发生修改。

深克隆-出现问题

1.创建Student类

    创建Student类,属性为String类型的name,int类型的age,还有引用类型的 address。

package com.wx.qianKeLong;

public class Student implements Cloneable{
    private String  name;
    private int age;

    private Address address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Student student = null;
        student = (Student) super.clone();
        //student.address = (Address) address.clone();
        return student;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

2.创建Address类

  创建Address类,属性为String类型的name

package com.wx.qianKeLong;

public class Address implements Cloneable{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Address{" +
                "name='" + name + '\'' +
                '}';
    }
}

3.创建测试类

    在测试类中,创建student对象,然后创建Address对象,对student对象中address属性进行赋值。然后对student对象进行克隆。克隆之后对address对象中name属性进行修改。如果是深克隆的话,对address对象进行修改,改变的话应该是student对象中的address属性,可是结果确实两个对象都发生修改,因此此克隆是浅克隆,没有对引用类型进行克隆,引用类型依然是引用的赋值。

package com.wx.qianKeLong;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        Address address= new Address();
        address.setName("China");
        student.setName("wx");
        student.setAge(24);
        student.setAddress(address);
        Student student1 = (Student) student.clone();
        address.setName("American");
        System.out.println(student);
        System.out.println(student1);
        System.out.println("===============================");
    }
}

结果

                                

解决深克隆出现的问题

1.创建student对象

   创建student对象,属性是String类型的name,int类型的age,Address类型的address

package com.wx.qianKeLong;

public class Student implements Cloneable{
    private String  name;
    private int age;

    private Address address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Student student = null;
        student = (Student) super.clone();
        student.address = (Address) address.clone();
        return student;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

2.创建address对象

  创建Address类,实现Cloneable接口,重写clone()方法。

package com.wx.qianKeLong;

public class Address implements Cloneable{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Address{" +
                "name='" + name + '\'' +
                '}';
    }
}

3.创建测试类

在测试类中,首先对student中的属性进行赋值,然后进行克隆。克隆之后的对象是student2.此时对address中的name属性进行修改,发现student中的address属性发生修改,而克隆之后的address属性没有修改。因为address属性是属于student的,在克隆后student1的address也进行克隆。此时address对name属性进行修改只会影响sutdent而不会影响student1.

package com.wx.qianKeLong;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        Address address= new Address();
        address.setName("China");
        student.setName("wx");
        student.setAge(24);
        student.setAddress(address);
        Student student1 = (Student) student.clone();
        address.setName("American");
        System.out.println(student);
        System.out.println(student1);
        System.out.println("===============================");
    }
}

结果

                             

深克隆进阶-采用序列化和反序列话进行克隆

  如果,在克隆中,多个类采用层层继承,那么在使用深克隆的时候就会产生在每一个类中都要重写clone方法,然后进行克隆。太过于繁琐。为了避免此问题,可以采用序列化和反序列化进行克隆。

1.创建Outer类

    创建Outer类,属性为String类型的name,Inner类型的inner。然后创建getInstance方法,进行序列化和反序列化操作。

package com.wx.xuLieHuaKeLong;

import java.io.*;

public class Outer implements Serializable{
    private String name;
    private Inner inner;

    public Inner getInner() {
        return inner;
    }

    public void setInner(Inner inner) {
        this.inner = inner;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Outer{" +
                "name='" + name + '\'' +
                ", inner=" + inner +
                '}';
    }

    private static final long serialVersionUID = 123712831982744L;
    public Outer getInstance(){
        Outer outer = null;
        try {
            //将对象转化为流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);
            //将流转化为对象
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            outer = (Outer) objectInputStream.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return  outer;
    }
}

2.创建Inner类

创建inner类,实现serializable

package com.wx.xuLieHuaKeLong;

import java.io.Serializable;

public class Inner implements Serializable{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Inner{" +
                "name='" + name + '\'' +
                '}';
    }
}

3.创建Test测试类

创建outer对象,然后getinstance进行克隆,克隆之后对inner属性进行修改,只影响outer对象中inner的属性,instance对象中的inner属性不发生变化。

package com.wx.xuLieHuaKeLong;

public class Test {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.setName("zhangsan");
        Inner inner = new Inner();
        inner.setName("inner");
        outer.setInner(inner);
        Outer instance = outer.getInstance();
        inner.setName("inner-copy");
        instance.setName("lisi");
        System.out.println(instance);
        System.out.println(outer);
    }
}

结果

                                                

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园2.0是高校信息化建设的新阶段,它面对着外部环境变化和内生动力的双重影响。国家战略要求和信息技术的快速发展,如云计算、大数据、物联网等,为智慧校园建设提供了机遇,同时也带来了挑战。智慧校园2.0强调以服务至上的办学理念,推动了教育模式的创新,并对传统人才培养模式产生了重大影响。 智慧校园建设的解决之道是构建一个开放、共享的信息化生态系统,利用互联网思维,打造柔性灵活的基础设施和强大的基础服务能力。这种生态系统支持快速迭代的开发和持续运营交付能力,同时注重用户体验,推动服务创新和管理变革。智慧校园的核心思想是“大平台+微应用+开放生态”,通过解耦、重构和统一运维监控,实现服务复用和度融合,促进业务的快速迭代和自我演化。 智慧校园的总体框架包括多端协同,即“端”,它强调以人为心,全面感知和捕获行为数据。这涉及到智能感知设备、超级APP、校园融合门户等,实现一“码”或“脸”通行,提供线上线下服务端的无缝连接。此外,台战略是智慧校园建设的关键,包括业务台和数据台,它们支持教育资源域、教学服务域等多个领域,实现业务度融合和数据的全面治理。 在技术层面,智慧校园的建设需要分期进行,逐步解耦应用,优先发展轻量级应用,并逐步覆盖更多业务场景。技术升级路径包括业务数据化、数据业务化、校园设施智联化等,利用IoT/5G等技术实现设备的泛在互联,并通过人工智能与物联网技术的结合,建设智联网。这将有助于实现线上线下一网通办,提升校园安全和学习生活体验,同时支持人才培养改革和后勤管理的精细化。 智慧校园的建设不仅仅是技术的升级,更是对教育模式和管理方式的全面革新。通过构建开放、共享的信息化生态系统,智慧校园能够更好地适应快速变化的教育需求,提供更加个性化和高效的服务,推动教育创新和人才培养的高质量发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值