zoukankan      html  css  js  c++  java
  • Clone的理解

    首先看张表了解一下分类以及区别:

    类型 共同点 区别 什么情况下是所谓的类型
    深度克隆

    一个新的对象实例的所有

    变量都含有与原来的对象

    相同的值,对于基本类型

    复制一份新产生的对象

    非基本类型指向被复制的

    新对象

    若某个对象的属性都为基础类型,则

    它的clone为深度克隆

    浅度克隆

    非基本类型指向原对象,只

    是一个引用

    集合的默认clone或Add以及AddAll

    集合的构造方法

    System.arraycopy()

    要注意String的克隆是一个特例,首先要知道String克隆是一个浅度克隆,但是又因为String的特殊性,在克隆时会有两个String类型的引用,所以如果改变克隆得到的对象的值是不会改变被克隆的对象的值的(这里我们可以假定为深度克隆)

    但是StringBuffer以及StringBuilder就不能够这么认为了,如果想要实现这两个类型的深度克隆,我们必须在类的clone方法中进行主动拷贝操作

    一段代码来加强记忆:

    public class TestClone {
        public static void main(String[] args){
            ArrayList<InfoBean> lists=new ArrayList<>();
            
            lists.add(new InfoBean("zyf", 23));
            lists.add(new InfoBean("pyh", 18));
            lists.add(new InfoBean("zxh", 23));
    
            for(InfoBean ib:lists){
                System.out.println(ib);
            }
    //        浅度克隆
            ArrayList<InfoBean> lists2=(ArrayList<InfoBean>)lists.clone();
    //        深度克隆
            ArrayList<InfoBean> lists3=new ArrayList<>();
            for(int i=0;i<lists.size();i++){
                try {
                    lists3.add((InfoBean)lists.get(i).clone());
                } catch (CloneNotSupportedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    //        对list2浅度克隆的验证
            lists2.get(1).name="hhhhh";
            System.out.println("对list2浅度克隆的验证-----------------------------");
            for(InfoBean ib:lists){
                System.out.println(ib);
            }
    //        对list3深度克隆的验证
            lists3.get(1).name="zzzzzz";
            System.out.println("对list3浅度克隆的验证-----------------------------");
            for(InfoBean ib:lists){
                System.out.println(ib);
            }
            
        }
    }
    class InfoBean implements Cloneable{
        public String name;
        public int age;
        
        public InfoBean(String name,int age){
            this.name=name;
            this.age=age;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
        @Override
        public String toString() {
            return "InfoBean [name=" + name + ", age=" + age + "]";
        }
        
    }

    看一下输出结果:

    从输出结果可以说明一切了吧!

    接下来说一下实现克隆的3种基本方法:

    1 通过实现Cloneable接口并重写Object的clone方法实现浅度克隆
    2 通过实现Cloneable接口并重写Object的clone方法实现深度克隆
    3 通过对象的序列化和反序列化实现深度克隆

    第一种:

    class InfoBean implements Cloneable{
        public String name;
        public int age;
        
        public InfoBean(String name,int age){
            this.name=name;
            this.age=age;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
        @Override
        public String toString() {
            return "InfoBean [name=" + name + ", age=" + age + "]";
        }
        
    }

    第二种:

    class InfoBean implements Cloneable{
        public String name;
        public int age;
        
        public InfoBean(String name,int age){
            this.name=name;
            this.age=age;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
        @Override
        public String toString() {
            return "InfoBean [name=" + name + ", age=" + age + "]";
        }
        
    }
    class InfoBean2 implements Cloneable{
        public String name;
        public int age;
        public InfoBean bean;
        
        public InfoBean2(String name,int age){
            this.name=name;
            this.age=age;
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            InfoBean2 ib2=(InfoBean2)super.clone();
            ib2.bean=(InfoBean)bean.clone(); //这里的第二个bean是由上一句克隆过来的,是成员变量
            return ib2;
        }
        @Override
        public String toString() {
            return "InfoBean2 [name=" + name + ", age=" + age + ", bean=" + bean
                    + "]";
        }
        
    }

    第三种:

    class CloneUtil{
        public static<T extends Serializable>T clone(T obj){
            T cloneObj =null;
            try{
                ByteArrayOutputStream byteOut=new ByteArrayOutputStream();
                ObjectOutputStream objOut =new ObjectOutputStream(byteOut);
                objOut.writeObject(obj);
                objOut.close();
                ByteArrayInputStream byteIn =new ByteArrayInputStream(byteOut.toByteArray());
                ObjectInputStream objIn =new ObjectInputStream(byteIn);
                cloneObj =(T)objIn.readObject();
                objIn.close();
            }catch(IOException e){
                e.printStackTrace();
            }catch(ClassNotFoundException e){
                e.printStackTrace();
            }
            return cloneObj;
        }
    }
  • 相关阅读:
    Uva 11754(枚举+中国剩余定理)
    poj 1018(枚举+贪心)
    Uva 11021(概率)
    UVa 11426
    unittest(二)框架中的概念与断言
    unittest(一)IDE导出的代码分析
    Selenium(十五)cookie
    Selenium(十四)处理登录框的验证码
    Selenium(十三)调用js,控制浏览器的滚动条
    安装pytest
  • 原文地址:https://www.cnblogs.com/zzl521/p/8992308.html
Copyright © 2011-2022 走看看