• java 克隆


      有些时候,我们需要对创建一个和已有对象A完全相同的新对象B,但是这个B不是A的引用,即A和B是两个完全独立的对象,虽然他们的属性相同,修改A的任何属性都不会对B产生影响,这个时候就要用到clone啦

    clone有两种:

    1深克隆:对克隆对象中所有的引用属性对象都进行克隆。

    2浅克隆:仅克隆对象的基本类型数据和引用,即只克隆引用对象的地址,而不是克隆被引用的对象。(String类型除外,它表面上和基本类型一样实现了深克隆)

    下面通过举例说明

    1、深克隆

    public class Test {
        public static void main(String[] args)
        {
            Stu stu1=new Stu();
            stu1.setAge(5);
            stu1.setName("Zhang");
            
            Stu stu2=(Stu)stu1.clone();
            stu2.setName("Cheng");
            
            System.out.println(stu1.getAge());
            System.out.println(stu1.getName());
            System.out.println(stu2.getAge());
            System.out.println(stu2.getName());
        }
    }
    public class Stu implements Cloneable{
        String name;
        int age;
        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 Object clone()
        {
            Stu stu=null;
            try{
                stu=(Stu)super.clone();
            }catch(CloneNotSupportedException ex)
            {
                ex.printStackTrace();
            }
            return stu;
        }
    }

    输出:

    5
    Zhang
    5
    Cheng

      克隆有两点需要注意:1.必须实现Cloneable接口,假如不实现这个接口直接实现clone方法会抛出CloneNotSupport异常

                2、必须实现clone方法,且方法必须是public的,这是因为Object本身就有个方法clone,不过这个方法时protected,另外这个方法时native方法,      效率比非native方法高。

    2、浅拷贝

    public class Stu implements Cloneable{
        String name;
        int age;
        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 String toString()
        {
            return "age="+age+"   name="+name;
        }
    }
    
    public class Test {
        static class League implements Cloneable
        {
            int level;
            Stu stu;
            public int getLevel() {
                return level;
            }
            public void setLevel(int level) {
                this.level = level;
            }
            public Stu getStu() {
                return stu;
            }
            public void setStu(Stu stu) {
                this.stu = stu;
            }
            public String tosString()
            {
                return "level="+level+"    age="+stu.getAge()+"   name="+stu.getName();
            }
            
            public Object clone()
            {
                League league=null;
                try{
                    league=(League)super.clone();
                }catch(CloneNotSupportedException ex)
                {
                    ex.printStackTrace();
                }
                //league.stu=(Stu)stu.clone();
                return league;
            }
        }
        public static void main(String[] args)
        {
            Stu stu1=new Stu();
            stu1.setAge(5);
            stu1.setName("Zhang");
            
            League league1=new League();
            league1.setLevel(2);
            league1.setStu(stu1);
            League league2=(League)league1.clone();
            league2.getStu().setName("Cheng");
            System.out.println(league1.tosString());
            System.out.println(league2.tosString());
        }
    }

    输出:

    level=2    age=5   name=Cheng
    level=2    age=5   name=Cheng

    这里进行克隆过后,对克隆对象的修改会影响到被克隆对象,那么怎么才能避免呢

    只要在League的对象属性Stu,也实现Clone即可,另外在League的clone方法里面加上league.stu=(Stu)stu.clone();即可

    如下

    public class Test {
        static class League implements Cloneable
        {
            int level;
            Stu stu;
            public int getLevel() {
                return level;
            }
            public void setLevel(int level) {
                this.level = level;
            }
            public Stu getStu() {
                return stu;
            }
            public void setStu(Stu stu) {
                this.stu = stu;
            }
            public String tosString()
            {
                return "level="+level+"    age="+stu.getAge()+"   name="+stu.getName();
            }
            
            public Object clone()
            {
                League league=null;
                try{
                    league=(League)super.clone();
                }catch(CloneNotSupportedException ex)
                {
                    ex.printStackTrace();
                }
                league.stu=(Stu)stu.clone();
                return league;
            }
        }
        public static void main(String[] args)
        {
            Stu stu1=new Stu();
            stu1.setAge(5);
            stu1.setName("Zhang");
            
            League league1=new League();
            league1.setLevel(2);
            league1.setStu(stu1);
            League league2=(League)league1.clone();
            league2.getStu().setName("Cheng");
            System.out.println(league1.tosString());
            System.out.println(league2.tosString());
        }
    }
    
    public class Stu implements Cloneable{
        String name;
        int age;
        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 String toString()
        {
            return "age="+age+"   name="+name;
        }
        public Object clone()
        {
            Stu stu=null;
            try{
                stu=(Stu)super.clone();
            }catch(CloneNotSupportedException ex)
            {
                ex.printStackTrace();
            }
            return stu;
        }
    }

    输出
    level=2    age=5   name=Zhang
    level=2    age=5   name=Cheng

    另外不是所有的类都可以实现深度克隆的,包含StringBuilder的类不能被深度克隆,因为该类没有重载clone方法,并且该类是一个final类,无法实现clone。

    小弟菜鸟一枚,初来乍到,有什么错误还望各位大神不吝指出,^_^。
  • 相关阅读:
    穷举字符串的一种算法
    使用VirtualBox SDK之初步编译
    Install Shield 中判断安装还是卸载
    [转] win32内核程序中进程的pid,handle,eprocess之间相互转换的方法
    如何做PHD (1)
    在TFS 2010中使用邮件提醒功能(Email Notification)
    Chrome的Awesome Screenshot的插件离线下载
    Visual Studio 2010下生成Crypto++ lib
    VirtualBox开发环境的搭建详解
    VC版PwdHash
  • 原文地址:https://www.cnblogs.com/maydow/p/4461073.html
Copyright © 2020-2023  润新知