• java基础---->Java关于复制的使用(一)


      这里简单记录一下java中关于浅复制和深复制的知识。很多时候,一个人选择了行走,不是因为欲望,也并非诱惑,他仅仅是听到了自己内心的声音。

    java中的复制clone方法

    一、java对象的浅复制

      一个实现了Cloneable并重写了clone方法的类A,有一个无参构造或有参构造B,通过new关键字产生了一个对象S,再然后通过S.clone()方式产生了一个新的对象T,那么在对象拷贝时构造函数B是不会被执行的

    public class Thing implements Cloneable {
        //定义一个私有变量
        private ArrayList<String> arrayList = new ArrayList<String>();
    
        public Thing() {
            System.out.println("构造函数被执行了......");
        }
    
        @Override
        protected Thing clone() {
            Thing thing = null;
            try {
                thing = (Thing) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return thing;
        }
    
        //设置HashMap的值
        public void setValue(String value) {
            this.arrayList.add(value);
        }
    
        //取得arrayList的值
        public List<String> getValue() {
            return this.arrayList;
        }
    }

      Thing类实现了Cloneable接口,并重写了Object的clone方法,里面有一个ArrayList列表的私有变量。现在我们的测试代码如下:

    package com.linux.huhx.learn.clone;
    
    /**
     * @Author: huhx
     * @Date: 2017-12-26 上午 10:57
     */
    public class ClientMain {
        public static void main(String[] args) {
            // 产生一个对象
            Thing thing = new Thing();
            thing.setValue("huhx");
    
            // 复制一个对象
            Thing cloneThing = thing.clone();
            cloneThing.setValue("linux");
            System.out.println(thing.getValue());
        }
    }

    运行的结果如下:

    构造函数被执行了......
    [huhx, linux]

      从结果我们可以看到:thing.clone()执行并没有再次调用构造函数,复制后的对象和原对象共享私有变量arrayList,也就是说复制对象对arrayList的操作会映射到原对象的arrayList。这样的浅拷贝是有风险的,下面我们介绍一下怎样实现对象的深复制。我们只需要在Thing类中clone方法加上数组的复制代码就可以,clone方法的代码如下:

    @Override
    protected Thing clone() {
        Thing thing = null;
        try {
            thing = (Thing) super.clone();
            thing.arrayList = (ArrayList<String>) this.arrayList.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return thing;
    }

      现在再执行ClientMain的main方法,打印的结果如下:可以看到原对象的arrayList并没有改变。

    构造函数被执行了......
    [huhx]

      需要注意的是:对象的clone与对象内的final关键字是有冲突的,我们修改Thing类的私有变量arrayList的修饰符。

    private final ArrayList<String> arrayList = new ArrayList<String>();

      通过ide我们可以看到在thing.arrayList = (ArrayList<String>) this.arrayList.clone();代码处会有编译报错。所以要想实现对象的深复制,类的成员变量上不要增加final关键字。

    Cannot assign a value to final variable 'arrayList'

    友情链接

  • 相关阅读:
    Silverlight“.NET研究” 2.5D RPG游戏技巧与特效处理:(七)动画特写 狼人:
    Silverlight 2.5D RPG游戏“.NET研究”技巧与特效处理:(六)流光追影 狼人:
    WPF中使用amCh“.NET研究”arts绘制股票K线图 狼人:
    验证.N“.NET研究”ET强命称的思路和实例 狼人:
    ASP.NET“.NET研究”下用URLRewriter重写二级域名 狼人:
    spring初始化在ServletContextListener实现类中获取spring注入对象
    执行原因【菜鸟笔记】Ubuntu系统shellscript中 关于for循环以及declare出错的原因
    jqueryfunctionchrome浏览器不支持 onmouseleave事件的解决
    异步线程C#异步委托的使用
    android删除android拦截短信并删除该条短信
  • 原文地址:https://www.cnblogs.com/huhx/p/baseusejavaclone1.html
Copyright © 2020-2023  润新知