zoukankan      html  css  js  c++  java
  • java基础入门-对象的浅克隆与深克隆

    这里面涉及到两个类,一个是person类,一个是测试类test


    首先我们说到的是浅克隆,对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,如果是基本数据类型(int,float,char等)到没什么问题,基本遇上如string,Integer等不可变对象的时候也没有什么问题,但是如果遇上了date这个可变对象,或者是自己定义的可变对象,他只是简单的复制一下引用这些可变对象,而不是把这些可变对象再一次的复制


    先上person类,这里面虽然是实现Cloneable接口,但是里面没有重写方法,只是super了一下就算了


    package com.ray.object;
    
    import java.util.Date;
    
    /**
     * 人
     * 
     * @author ray
     * @since 2015-05-07
     * @version 1.0
     * 
     */
    public class Person implements Cloneable {
    
    	private int id = 0;
    	private String name = "";
    	private Date birthday = null;
    
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public Date getBirthday() {
    		return birthday;
    	}
    
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    
    	@Override
    	protected Object clone() {
    		Object obj = null;
    		try {
    			obj = super.clone();
    		} catch (CloneNotSupportedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return obj;
    	}
    
    }
    


    再上测试类

    package com.ray.object;
    
    import java.util.Date;
    
    /**
     * 浅克隆和深克隆
     * 
     * @author ray
     * @since 2015-05-07
     * @version 1.0
     * 
     */
    public class Test {
    
    	public static void main(String[] args) {
    		Person bill = new Person();
    		bill.setId(1);
    		bill.setName("bill");
    		bill.setBirthday(new Date());
    		System.out.println("bill.getId() --- "+bill.getId());
    		System.out.println("bill.getName() --- "+bill.getName());
    		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
    		Person jack = (Person) bill.clone();
    		System.out.println("jack.getId() --- "+jack.getId());
    		System.out.println("jack.getName() --- "+jack.getName());
    		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
    		try {
    			Thread.sleep(2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		Date jacksBirthday = jack.getBirthday();
    		jacksBirthday.setTime(System.currentTimeMillis());
    		System.out.println("bill.getId() --- "+bill.getId());
    		System.out.println("bill.getName() --- "+bill.getName());
    		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
    		System.out.println("jack.getId() --- "+jack.getId());
    		System.out.println("jack.getName() --- "+jack.getName());
    		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
    	}
    }
    


    输出:

    bill.getId() --- 1
    bill.getName() --- bill
    bill.getBirthday() --- Thu May 07 08:56:33 CST 2015
    jack.getId() --- 1
    jack.getName() --- bill
    jack.getBirthday() --- Thu May 07 08:56:33 CST 2015
    bill.getId() --- 1
    bill.getName() --- bill
    bill.getBirthday() --- Thu May 07 08:56:35 CST 2015
    jack.getId() --- 1
    jack.getName() --- bill
    jack.getBirthday() --- Thu May 07 08:56:35 CST 2015




    由上面可以看见,基本jack这个对象是clone了bill这个对象,但是这里面只是简单复制一下引用,当我们修改jack对象里面的生日时,bill的生日竟然也跟着变了



    下面,我们再说一下深克隆,就是把对象的所有域全部复制一份


    先上Person类,这次Person类重写了clone方法,除了super之外,还把里面的birthday属性也复制一份


    package com.ray.object;
    
    import java.util.Date;
    
    /**
     * 人
     * 
     * @author ray
     * @since 2015-05-07
     * @version 1.0
     * 
     */
    public class Person implements Cloneable {
    
    	private int id = 0;
    	private String name = "";
    	private Date birthday = null;
    
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public Date getBirthday() {
    		return birthday;
    	}
    
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    
    	@Override
    	protected Object clone() {
    		Object obj = null;
    		try {
    			obj = super.clone();
                            //下面把生日也复制一份
    			Person person = (Person) obj;
    			person.birthday = (Date) birthday.clone();
    		} catch (CloneNotSupportedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return obj;
    	}
    
    }
    

    再上Test类,其实Test类没有做任何的改动,这里只是为了阅读方便,也写上了


    package com.ray.object;
    
    import java.util.Date;
    
    /**
     * 浅克隆和深克隆
     * 
     * @author ray
     * @since 2015-05-07
     * @version 1.0
     * 
     */
    public class Test {
    
    	public static void main(String[] args) {
    		Person bill = new Person();
    		bill.setId(1);
    		bill.setName("bill");
    		bill.setBirthday(new Date());
    		System.out.println("bill.getId() --- "+bill.getId());
    		System.out.println("bill.getName() --- "+bill.getName());
    		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
    		Person jack = (Person) bill.clone();
    		System.out.println("jack.getId() --- "+jack.getId());
    		System.out.println("jack.getName() --- "+jack.getName());
    		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
    		try {
    			Thread.sleep(2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		Date jacksBirthday = jack.getBirthday();
    		jacksBirthday.setTime(System.currentTimeMillis());
    		System.out.println("bill.getId() --- "+bill.getId());
    		System.out.println("bill.getName() --- "+bill.getName());
    		System.out.println("bill.getBirthday() --- "+bill.getBirthday());
    		System.out.println("jack.getId() --- "+jack.getId());
    		System.out.println("jack.getName() --- "+jack.getName());
    		System.out.println("jack.getBirthday() --- "+jack.getBirthday());
    	}
    }
    



    输出:

    bill.getId() --- 1
    bill.getName() --- bill
    bill.getBirthday() --- Thu May 07 09:22:03 CST 2015
    jack.getId() --- 1
    jack.getName() --- bill
    jack.getBirthday() --- Thu May 07 09:22:03 CST 2015
    bill.getId() --- 1
    bill.getName() --- bill
    bill.getBirthday() --- Thu May 07 09:22:03 CST 2015
    jack.getId() --- 1
    jack.getName() --- bill
    jack.getBirthday() --- Thu May 07 09:22:05 CST 2015




    由上面的输出可以看到,jack里面birthday的改动不再影响bill里面的birthday



    最后,我们来说一下使用=来copy对象,其实只是把对象的引用复制一份过去给另外的对象,对象是没有做出任何改变

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    01_javaSE面试题:自增变量
    SpringBoot(二十)_404返回统一异常处理结果
    MD5加密工具代码
    SpringBoot(十九)_spring.profiles.active=@profiles.active@ 的使用
    读取本地文件转化成MultipartFile
    remote: http basic: access denied fatal: authentication failed for '‘解决办法
    git报错_you are not allowed to push code to protected branches on this project
    SpringBoot(十八)_springboot打成war包部署
    sql优化问题笔记(mysql)
    gitbook 简单使用
  • 原文地址:https://www.cnblogs.com/raylee2007/p/4774571.html
Copyright © 2011-2022 走看看