理解java中的对象克隆

理解java中的对象克隆

一、什么是对象克隆

所谓的对象克隆描述的概念就是进行对象的复制,当一个对象完成之后实际上都会自动的开辟内存空间,在每一块堆内存空间里面都会保存有对象的相关属性内容,所谓的对象克隆它描述的就是属性的复制。

如果想要完成对象的克隆操作实际上它不需要由用户特别复杂的进行处理,因为在Object类里面提供有一个专属的对象克隆的处理方法,此方法定义如下:

protected Object clone()
                throws CloneNotSupportedException

源代码:

protected native Object clone() throws CloneNotSupportedException;

通过clone()方法的定义可以发现,这个方法的操作实质上是利用了JVM底层完成的内存空间的复制处理,如果要想复制对象就必须使用指定的方法完成,同时该方法上会抛出一个“CloneNotSupportedException”异常。如果要克隆对象所处的类没有实现Cloneable接口,那么就会出现上述异常,这个Cloneable接口是在JDK1.0的时候就提供的支持,同时该接口中并没有提供任何的处理方法,所以此接口属于一中标识性的接口,表示一种能力。

jdkapi_Object_clone()

通过以下范例来观察对象的处理:

package com.itheima.jiuyeban.对象克隆;

class Emp implements Cloneable{//表示该类的对象实例允许克隆
    private String ename;
    private String job;

    public Emp(String ename, String job) {
        this.ename = ename;
        this.job = job;
    }

    @Override
    public String toString() {//父类中的toString()可以返回一个内存地址编码
        return "【Emp = "+super.toString()+"】姓名:"+this.ename+"、职位:"+this.job;
    }

    /**
     * 注意:clone方法默认的是protected访问权限,为了让此方法对其他外部的类可见,修改为public
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class CloneDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Emp empA = new Emp("张三","java工程师");//原始对象
        Emp empB = (Emp) empA.clone();
        System.out.println(empA);
        System.out.println(empB);

    }
}

执行结果:

【Emp = com.itheima.jiuyeban.对象克隆.Emp@1540e19d】姓名:张三、职位:java工程师
【Emp = com.itheima.jiuyeban.对象克隆.Emp@677327b6】姓名:张三、职位:java工程师

此时两个对象的编码内容不同,所以得出结论:利用empA对象的堆内存空间拷贝得到了empB对象的新的堆内存空间,同时两个空间中的属性内容完全相同。

二、深克隆和浅克隆

在实际的程序开发过程之中如果要想进行对象克隆的处理一般会有两种做法:深克隆和浅克隆。

深克隆:所有与对象相关的引用类型全部进行克隆;

浅克隆:只克隆当前类中的基本属性内容。

**注意:**在Object类中提供的clone()方法实际上属于浅克隆。

修改后的范例:

package com.itheima.jiuyeban.对象克隆;

class Dept{//部门类
    private String dName;
    private String loc;

    public Dept(String dName, String loc) {
        this.dName = dName;
        this.loc = loc;
    }

    public void setdName(String dName) {
        this.dName = dName;
    }

    @Override
    public String toString() {
        return "【Dept = "+super.toString()+"】部门名称:"+this.dName+"、部门位置:"+this.loc;
    }
}
class Emp implements Cloneable{//表示该类的对象实例允许克隆
    private String ename;
    private String job;
    private Dept dept;//部门引用
    public Emp(String ename, String job,Dept dept) {
        this.ename = ename;
        this.job = job;
        this.dept = dept;
    }

    public Dept getDept() {
        return dept;
    }

    @Override
    public String toString() {//父类中的toString()可以返回一个内存地址编码
        return "【Emp = "+super.toString()+"】姓名:"+this.ename+"、职位:"+this.job;
    }

    /**
     * 注意:clone方法默认的是protected访问权限,为了让此方法对其他外部的类可见,修改为public
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class CloneDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Dept dept= new Dept("研发部","杭州");//部门对象
        Emp empA = new Emp("张三","java工程师",dept);//原始对象
        Emp empB = (Emp) empA.clone();
        dept.setdName("技术部");
        System.out.println(empA);
        System.out.println("\t|- "+empA.getDept());
        System.out.println("----------------------避免晕眩的分割线------------------------");
        System.out.println(empB);
        System.out.println("\t|- "+empB.getDept());
    }
}

执行结果:

【Emp = com.itheima.jiuyeban.对象克隆.Emp@1540e19d】姓名:张三、职位:java工程师
	|- 【Dept = com.itheima.jiuyeban.对象克隆.Dept@677327b6】部门名称:技术部、部门位置:杭州
----------------------避免晕眩的分割线------------------------
【Emp = com.itheima.jiuyeban.对象克隆.Emp@14ae5a5】姓名:张三、职位:java工程师
	|- 【Dept = com.itheima.jiuyeban.对象克隆.Dept@677327b6】部门名称:技术部、部门位置:杭州

##三、内存结构

下面通过具体的内存结构分析来对深浅克隆技术做一个区分。

浅克隆

深克隆

区别

深克隆和浅克隆的主要区别是看你是否要克隆对象之中其他引用结构对应的操作数据。

总结:

通过以上的执行对比就可以清楚克隆整体的执行结构,很多的编程语言都有这样的深克隆和浅克隆的概念,如果想要实现深克隆就需要通过程序逻辑实现手工的拷贝处理,要想实现这样的机制就必须熟悉反射机制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值