• 浅拷贝,深拷贝


    浅拷贝

    浅拷贝结果是:新对像中包含的引用对象和原对象中包含的引用对象是同一个东东, 改变其中任何一个所包含的引用对象, 另一个也会受到影响

    深拷贝

    深拷贝结果是:新对象与原对象是完全独立的, 改变其中任何一个所包含的引用对像, 另一个都不会受到影响

    浅拷贝例子  Object中的clone默认是浅拷贝

    1 实现cloneable接口,这是个标记接口

    2 重写Object的clone方法,调用父类的clone方法

    public class Student {
        private String name; // 姓名
        private int age; // 年龄
        private StringBuffer sex; // 性别
    
        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 StringBuffer getSex() {
            return sex;
        }
    
        public void setSex(StringBuffer sex) {
            this.sex = sex;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
        }
    }
    public class School implements Cloneable {
        private String schoolName; // 学校名称
        private int stuNums; // 学校人数
        private Student stu; // 一个学生
    
        public String getSchoolName() {
            return schoolName;
        }
    
        public void setSchoolName(String schoolName) {
            this.schoolName = schoolName;
        }
    
        public int getStuNums() {
            return stuNums;
        }
    
        public void setStuNums(int stuNums) {
            this.stuNums = stuNums;
        }
    
        public Student getStu() {
            return stu;
        }
    
        public void setStu(Student stu) {
            this.stu = stu;
        }
    
        
        
        @Override
        protected School clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return (School)  super.clone();
        }
    
        
        @Override
        public String toString() {
            return "School [schoolName=" + schoolName + ", stuNums=" + stuNums + ", stu=" + stu + "]";
        }
        
        
        public static void main(String[] args) throws CloneNotSupportedException {
            School s1 = new School();
            s1.setSchoolName("实验小学");
            s1.setStuNums(100);
            Student stu1 = new Student();
            stu1.setAge(20);
            stu1.setName("zhangsan");
            stu1.setSex(new StringBuffer(""));
            s1.setStu(stu1);
            System.out.println(    "s1: " + s1 + " s1的hashcode:" + s1.hashCode() + "  s1中stu1的hashcode:" + s1.getStu().hashCode());
            School s2 = s1.clone(); // 调用重写的clone方法,clone出一个新的school---s2
            System.out.println("s2: " + s2 + " s2的hashcode:" + s2.hashCode() + " s2中stu1的hashcode:" + s2.getStu().hashCode());
    
        }
    }

    s1和s2是不同的对象,但是他们包含的学生是同一个对象

    s1: School [schoolName=实验小学, stuNums=100, stu=Student [name=zhangsan, age=20, sex=男]] s1的hashcode:366712642 s1中stu1的hashcode:1829164700
    s2: School [schoolName=实验小学, stuNums=100, stu=Student [name=zhangsan, age=20, sex=男]] s2的hashcode:2018699554 s2中stu1的hashcode:1829164700

    深拷贝

    1 学生类实现cloneable接口

    2 学生类重写clone方法

    3 修改学校类的clone方法

    public class Student implements Cloneable {
    
        private String name;
        private int age;
        private StringBuffer sex;
    
        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 StringBuffer getSex() {
            return sex;
        }
    
        public void setSex(StringBuffer sex) {
            this.sex = sex;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
        }
    
        @Override
        protected Student clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return (Student) super.clone();
        }
    }
    public class School implements Cloneable {
        private String schoolName; // 学校名称
        private int stuNums; // 学校人数
        private Student stu; // 一个学生
    
        public String getSchoolName() {
            return schoolName;
        }
    
        public void setSchoolName(String schoolName) {
            this.schoolName = schoolName;
        }
    
        public int getStuNums() {
            return stuNums;
        }
    
        public void setStuNums(int stuNums) {
            this.stuNums = stuNums;
        }
    
        public Student getStu() {
            return stu;
        }
    
        public void setStu(Student stu) {
            this.stu = stu;
        }
    
        @Override
        protected School clone() throws CloneNotSupportedException {
            School s = null;
            s = (School) super.clone();
            s.stu = stu.clone();
            return s;
        }
    
        @Override
        public String toString() {
            return "School [schoolName=" + schoolName + ", stuNums=" + stuNums + ", stu=" + stu + "]";
        }
    
        public static void main(String[] args) throws CloneNotSupportedException {
            School s1 = new School();
            s1.setSchoolName("实验小学");
            s1.setStuNums(100);
            Student stu1 = new Student();
            stu1.setAge(20);
            stu1.setName("zhangsan");
            stu1.setSex(new StringBuffer(""));
            s1.setStu(stu1);
            System.out.println("s1: " + s1 + " s1的hashcode:" + s1.hashCode() + "  s1中stu1的hashcode:" + s1.getStu().hashCode());
            School s2 = s1.clone(); // 调用重写的clone方法,clone出一个新的school---s2
            System.out.println("s2: " + s2 + " s2的hashcode:" + s2.hashCode() + " s2中stu1的hashcode:" + s2.getStu().hashCode());
    
            // 修改s2中的值,看看是否会对s1中的值造成影响
            s2.setSchoolName("希望小学");
            s2.setStuNums(200);
            Student stu2 = s2.getStu();
            stu2.setAge(30);
            stu2.setName("lisi");
            stu2.setSex(stu2.getSex().append("6666666"));
            s2.setStu(stu2);
    
            // 再次打印两个school,查看结果
            System.out.println("-------------------------------------------------------------------------");
            System.out.println("s1: " + s1 + " hashcode:" + s1.hashCode() + "  s1中stu1的hashcode:" + s1.getStu().hashCode());
            System.out.println("s2: " + s2 + " hashcode:" + s2.hashCode() + " s2中stu1的hashcode:" + s2.getStu().hashCode());
    
        }
    }

    s1: School [schoolName=实验小学, stuNums=100, stu=Student [name=zhangsan, age=20, sex=男]] s1的hashcode:366712642 s1中stu1的hashcode:1829164700
    s2: School [schoolName=实验小学, stuNums=100, stu=Student [name=zhangsan, age=20, sex=男]] s2的hashcode:2018699554 s2中stu1的hashcode:1311053135
    -------------------------------------------------------------------------
    s1: School [schoolName=实验小学, stuNums=100, stu=Student [name=zhangsan, age=20, sex=男6666666]] hashcode:366712642 s1中stu1的hashcode:1829164700
    s2: School [schoolName=希望小学, stuNums=200, stu=Student [name=lisi, age=30, sex=男6666666]] hashcode:2018699554 s2中stu1的hashcode:1311053135

    可以修改s2中的性别,s1的也发生了改变,原因在于sex的类型是Stringbuffer,属于引用类型,在clone的时候将StringBuffer对象的地址传递了过去

    这种情况应该怎么解决呢?

    修改学生类的clone方法,设置sex时创建一个新的StringBuffer对象



  • 相关阅读:
    【搜索】棋盘 luogu-3956
    【动态规划】石子合并 luogu-1880
    【动态规划】合唱队形 luogu-
    【模拟】报名签到 luogu-4445
    【排序+贪心】导弹拦截 luogu-1158
    【模拟】不高兴的津津
    【模拟】选数 luogu-1037
    「JOISC2020」建筑装饰 4
    「清华集训」小 Y 和恐怖的奴隶主
    「CF708E」Student's Camp
  • 原文地址:https://www.cnblogs.com/moris5013/p/10697701.html
Copyright © 2020-2023  润新知