java clone

原创 2015年11月19日 11:00:30

我们知道Object对象中存在一个clone()方法,他的主要目的就是实现对象的拷贝,从而产生一个新的对象,这两个对象具有相同的值但是存在不同的地址,那么如果我们重写这个方法,应该注意哪些要点呢

1、如果我们需要重写clone()方法,那么我们需要在类中实现Cloneable接口,否则我们重写clone()方法的时候可能会抛出CloneNotSupportedException异常

2、除了声明实现了Cloneable接口以外,我们必须对Object受保护的clone方法提供public的访问权限

因为Object类中提供的clone方法是这样的:

protected native Object clone() throws CloneNotSupportedException;

3、重写的clone方法我们完全没有必要返回Object类型的对象,而是直接返回我们clone的对象类型,因为java1.5已经指出覆盖方法的返回类型可以是被覆盖方法的返回类型的子类了,所有我们只需要返回我们clone的对象类型就可以了,这样不仅优化了代码,还免去了在其他代码上通过强制转换获得对象的开销

4、这个也是非常重要的,我们可能都听说过深拷贝和浅拷贝,但是不知道他们之间到底有什么不同,下面我将做出一定的解释并给出一个实例

前面已经提到clone()方法其实是产生一个具有相同值但是具有不同内存地址的不同对象

那么我们可以更好理解浅拷贝的意思了,浅拷贝就会产生一个具有相同值并且具有相同内存地址的对象,这对于程序来说是应该极力回避的,因为我对这个对象做出的改变其实直接影响到了另一个对象,那么我们直接用赋值语句不更好的解决问题吗,就没有使用clone()方法的必要了

下面给出一个使用clone方法造成浅拷贝的一个实例,可以更好的理解为什么造成了浅拷贝:

class Person implements Cloneable{
	private String name;
	
	public Person(String name, int age) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public Person clone() throws CloneNotSupportedException{
		Person result=(Person)super.clone();
		return result;
	}
}

public class Copy implements Cloneable{
	private String name;
	private Person person;
	
	public Copy(String name,Person person) {
		super();
		this.name = name;
		this.person = person;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Person getPerson() {
		return person;
	}
	public void setPerson(Person person) {
		this.person = person;
	}
	
	@Override
	public Copy clone(){
		try {
			Copy copy=(Copy)super.clone();
			return copy;
		} catch (CloneNotSupportedException e) {
			throw(new AssertionError());
		}
	}
}

这段代码初略一看觉得很对,clone()方法是产生了两个不同的Copy对象,但是如果我们写一个main方法测试就会发现问题:

在main()方法里我们加上这两句话:

Copy a=new Copy("hehe",new Person("haha",22));
Copy b=a.clone();
System.out.println(a==b);
System.out.println(a.getName()==b.getName());
System.out.println(a.getPerson()==b.getPerson());

我们发现这里会输出false,true,true

也就是说我们拷贝了两个不同对象a,b,但是他们却占用相同的资源person和name,这其实是不对的,也就是我们所说的浅拷贝,就是没有正确的拷贝出两个完全不同的对象,那么我们应该怎么优化使得产生两个完全不同的对象呢,其实很简单,我们只需要修改Copy类的clone方法和Person类的clone方法就可以了:

person类clone方法:

@Override
public Person clone() throws CloneNotSupportedException{
	Person result=(Person)super.clone();
	result.name=new String(name);
	return result;
}
Copy的clone方法:

@Override
	public Copy clone(){
		try {
			Copy copy=(Copy)super.clone();
			copy.person=person.clone();
			copy.name=new String(name);
			return copy;
		} catch (CloneNotSupportedException e) {
			throw(new AssertionError());
		}
	}
这里由于String类型也不是基本类型,所有也需要进行clone,但是String是final类,不存在clone方法,所有我们直接new一个就可以了,就会产生两个不同对象了

这样我们把person也同样clone一份,那么就会产生两个不同的对象a,b,并且具有相同的值,两个对象之间不会产生任何的干扰

其实对于一个对象的深拷贝,我们首先需要调用super.clone()产生一个新的对象,然会需要对里面的属性进行修正,如果只包含基本类型的属性或者final对象的引用就基本没有修正的必要了,但是不排除序列号等需要修正的可能性。





相关文章推荐

Java clone方法使用

  • 2015年06月08日 20:52
  • 186KB
  • 下载

java Clone

  • 2008年07月25日 14:35
  • 71KB
  • 下载

Java的clone方法

什么是"clone"?    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A...

Java中的克隆(Clone)机制

  • 2007年07月16日 09:55
  • 49KB
  • 下载

Java深浅clone

  • 2013年07月25日 22:38
  • 10KB
  • 下载

Java中的clone方法详解

Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那...

java code clone

  • 2011年12月23日 00:15
  • 3KB
  • 下载

java clone的小例子

  • 2010年12月21日 20:51
  • 2KB
  • 下载

Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

Part I 没啥好说的,直接开始Part II吧。   Part II 谈到了对象的克隆,就不得不说为什么要对对象进行克隆。Java中所有的对象都是保存在堆中,而堆是供全局共...

java_clone用法

  • 2011年12月24日 01:29
  • 121KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java clone
举报原因:
原因补充:

(最多只允许输入30个字)