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()用法实例解析

1.背景         用java写程序的时候很苦恼的一件事就是,如果将一个对象a赋给另一个对象b,那么你改变a的变量值得时候,b的值也对应的变化。如果我们只想单纯的获取那个时刻的a的状况给b的话,...
  • gshengod
  • gshengod
  • 2015年02月03日 16:48
  • 3767

java之clone方法的使用

首先看一下jdk中对clone方法的解释: 大概意思是说:返回一个要克隆对象的副本,克隆的类型依赖被克隆对象,换句话说:克隆后的对象类型与被克隆对象的类型相同。 一、简单用法 只需要在需要clo...
  • Rebirth_Love
  • Rebirth_Love
  • 2016年06月30日 20:03
  • 5063

Java Clone方法之懒人实现

在Java的Object类中定义了(protected)clone()方法,如果自己的类需要clone方法的话需要实现Cloneable接口,并重写clone()方法和将方法访问级别改为(public...
  • kongxx
  • kongxx
  • 2010年12月07日 08:32
  • 2711

java clone详解

Clone使用方法详解 TOC /o"1-3" /h /z /u 1.    java“指针”...
  • baobeiSimple
  • baobeiSimple
  • 2007年08月05日 17:05
  • 8400

Java中数组的clone

先看实验代码: public static void main(String[] args) throws CloneNotSupportedException { // 测试一,数...
  • c289054531
  • c289054531
  • 2013年06月27日 15:50
  • 1394

详解Java中的clone方法 -- 原型模式

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

java 中的clone() 在数组中

今天在编程中遇到发现一个问题,那就是二维数组的clone,只有第一层clone了,里层的还是指向之前的地址 于是 就想到,clone() 函数 是不是对带引用的成员变量(非String的对象)都没有c...
  • jsplijun
  • jsplijun
  • 2015年11月14日 14:33
  • 1491

详解java中的clone方法

Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对...
  • u011514810
  • u011514810
  • 2016年08月28日 14:09
  • 4947

java中的clone()方法的研究---(8)如何编写正确的clone()方法:数组类型

在自定义类Person中,会有String, Integer 类型。我们总结的是,针对这些类型的字段,在clone()方法里面,不需要有特别的处理。 但是!!!!!!! String, Integer...
  • miqi770
  • miqi770
  • 2015年06月12日 16:56
  • 2485

神奇克隆术——Java深、浅Clone

本篇博客通过一个不断加强银行系统的例子来详细阐述了Java中深、浅Clone的区别,优点和缺陷。代码详细,分析细致。并提供了Java源码示例下载。希望我们一起在讨论中共同进步。...
  • qiumengchen12
  • qiumengchen12
  • 2015年04月13日 10:54
  • 2102
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java clone
举报原因:
原因补充:

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