关于clone


在java中我们时常会遇到需要对对象进行clone的情况,主要是因为Java的别名效应 如下:

 

SimpleObject a = new SimpleObject(); 
SimpleObject b = a; 
 

这个时候对b进行修改,a也会被改变.这个时候我们就需要对对象进行clone.

单个对象的clone很简单,实现cloneable接口并继承object clone方法就行了

package com.yecg.java.clone;

public class SimpleObject implements Cloneable{
   
	private String property;
    
	public SimpleObject(String property) {
		super();
		this.property = property;
	}

	public String getProperty() {
		return property;
	}

	public void setProperty(String property) {
		this.property = property;
	}
	
	public String toString(){
		return "simple object property is -----"+property;
	}
	
	public Object clone(){
		Object a =null;
		
		try {
			a =super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return a;
	}
	
}

 测试下:

package com.yecg.java.clone;

import java.util.ArrayList;

public class CloneTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//------simple clone
        SimpleObject a  = new SimpleObject("ini");
        SimpleObject b = (SimpleObject)a.clone();
        b.setProperty("clo");
        System.out.println(a);
        System.out.println(b);
       }

}
  结果:simple object property is -----ini

simple object property is -----clo  说明clone生效.

 

需要说明的是.虽然在object中有clone方法,但是是protect,也就是只有在子类中能用,使用a.clone()这种调用方式是不可能实现的.这是因为java要限制clone,并不是每个对象都有clone能力的,如果你想要这个对象拥有clone能力必须要继承这个方法并把它申明为public.

 

复杂对象的clone

这种方式的的clone只能说是浅度clone.为什么说是浅度clone,如果这个对象中还包含其他对象的引用的话,是无法把这个引用的对象也clone了的

举个例子:

package com.yecg.java.clone;

public class ComplexObject implements Cloneable {

	 private String property;
	 
	 private SimpleObject simpleObject;

	public String getProperty() {
		return property;
	}

	public void setProperty(String property) {
		this.property = property;
	}

	public SimpleObject getSimpleObject() {
		return simpleObject;
	}

	public void setSimpleObject(SimpleObject simpleObject) {
		this.simpleObject = simpleObject;
	}
	 
	public Object clone(){
	     Object a =null;
		
		try {
			a =super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return a;
	}
	
    public String toString(){
    	return "ComplexObject  property is ---"+property +" simpleObject property is ---"+simpleObject.getProperty();
    }
}

这里一个复杂的对象ComplexObject包含了一个简单对象SimpleObject的引用  ,clone的方法仍然和前面一样

测试下:

 

package com.yecg.java.clone;

import java.util.ArrayList;

public class CloneTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
        //complex clone
        SimpleObject simple  = new SimpleObject("ini");
        ComplexObject complex = new ComplexObject();
        complex.setProperty("complex_ini");
        complex.setSimpleObject(simple);
        
        ComplexObject complexClone =(ComplexObject)complex.clone();
        complexClone.setProperty("complex_clo");
        complexClone.getSimpleObject().setProperty("clo");
        System.out.println(complex);
        System.out.println(complexClone);
        
 
	}

}
  ComplexObject  property is ---complex_ini simpleObject property is ---clo

ComplexObject  property is ---complex_clo simpleObject property is ---clo

可以看到属性property是确实被clone,但属性simpleObject没有,clone后的simpleObject做了改变

 complexClone.getSimpleObject().setProperty("clo");

会影响到clone之前对象的值. 这就是浅度复制.只复制对象的表层.

 

那怎么进行深度复制呢,只需要改下clone方法:public Object clone(){

		ComplexObject a =null;
		
		try {
			a =(ComplexObject)super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		a.simpleObject =(SimpleObject)a.simpleObject.clone();
		return a;
	}
 

clone自己的同时,也把自己的对象属性进行clone.这就要求你的对象属性必须也要是可以clone的才可以.

集合的clone:

ArrayList里有clone方法,但和复杂对象的clone一样都是浅度clone.怎么深度clone

 

 ArrayList<SimpleObject> objectListClo = (ArrayList<SimpleObject>)objectList.clone();
        for(int i=0;i<objectListClo.size();i++){
        	objectListClo.set(i, (SimpleObject)objectListClo.get(i).clone());
        }

cloneobjectListClo后必须遍历objectListClo里面的每个对象,逐一clone.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值