java clone 之深拷贝、浅拷贝

由于指针不仅给开发人员带来使用上的不变,而且也是造成程序不稳定的根源,为了根除c++语言的这些缺点,java语言取消了指针的概念,但这只是在java语言中没有明确提供指针的概念与用法,二实质每个new语句返回的都是一个指针的引用,只不过在大部分情况下开发人员不需要关心如何取操作这个指针而已。因此,开发人员在编程中往往忽略了对象与引用的区别

  java在处理基本数据类型(byte,int ,short,long,float,double,char,boolean)时采用按值传递,传递的是输入参数的复制,除此之外的其他类型都是采用按引用传递,传递的对象的引用,实际上指向的是同一个对象。对象除了在函数调用时是引用传递,赋值时也是采用引用传递。

 在实际编程中,经常会遇到某个已有的对象A创建出另一个与A具有相同状态的对象B,并且对B的修改不会影响到A的状态。例如,prototype原型模式中就需要clone一个对象实例。java中仅仅通过简单的赋值操作显然无法达到这个目的。至此,clone正式登场。

clone()方法的使用步骤:

 1.首先继承cloneable 接口,一个标识接口。

 2.在类中重写object的clone方法

3.在clone方法中调用super.clone();

4.把潜复制的引用指向原型对象新的克隆体。

 

package com.dh.DpsdkCore.TvWall;

class Obj implements Cloneable {
    private int a = 0;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public void changint() {
        this.a = 1;
    }
    //重写clone方法
    public Object clone() {
        Object o = null;
        try {
            o = super.clone();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }

}


public class TestClone() {
    //jvm的入口
    public static void main (String[] args){
        Obj a=new Obj();
        Obj b=(Obj)a.clone();
        b.changint();
        System.out.println("a:"+a.getA());//0
        System.out.println("b:"+b.getA());//1
    }
    }
 

b的变化并没有影响到a.。

在c语言中,当开发人员自定义复制构造函数时,会存在潜复制和深复制之分。java在重载clone()时毕业存在同样的问题。当类中只有一些基本数据类型时,采用上述方法就可以了,但是当类中包含一些对象时,就需要用到深复制了。实现方法就是在对对象调用clone()完成复制后,接着则对对象中的非基本数据类型的属性也调用clone()来完成深复制。

 

package com.dh.DpsdkCore.TvWall;

import java.util.Date;

class Obj implements Cloneable {
    private int a = 0;
    private Date birth=new Date();

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public void changint() {
        this.a = 1;
    }
    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }
    //重写clone方法
    public Object clone() {
        Object o = null;
        try {
            o = super.clone();

        } catch (Exception e) {
            e.printStackTrace();
        }
         //实现深复制
        o.birth=(Date)this.getBirth().clone();
        return o;
    }
    

}
public class TestClone() {
    //jvm的入口
    public static void main (String[] args){
        Obj a=new Obj();
        Obj b=(Obj)a.clone();
        b.changint();
        System.out.println("a:"+a.getA());//0
        System.out.println("b:"+b.getA());//1
    }
    }


 

 

clone的保护机制:

在Object中Clone()是被申明为protected的,这样做是有一定的道理的。在Object中clone()是被声明为protected的,利用protected修饰clone()方法,是为了安全考虑。Object类中的clone方法是浅拷贝,如果是对象,它拷贝的只是这个对象的一个引用,而这个引用仍然指向那个对象,当我们改变这个引用的属性时,原来对象也会跟着改变,这不是我们希望看到的,但是Object类肯定做不到深拷贝,因为它不知道你的类里有哪些引用类型,所以把修饰符定义为protected,这样想要在其他任何地方调用这个类的clone方法,这个类就必须去重写clone方法并且把修饰符改为public,这样在任何地方都可以调用这个类的clone方法了。
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值