11、克隆

克隆是Object类中的一个protected修饰的方法,故只能被子类调用或重写,克隆会在栈中产生一个新引用,在堆中产生一个新对象,但是如果对象中有引用,则引用地址是被克隆的,即对象中的引用指向同一个变量(常量)

看如下代码

class Address
{
	String detail;
	public Address(String detail)
	{
		this.detail = detail;
	}
}

class User implements Cloneable
{
	int age;
	Address address;
	
	public User(int age,String address)
	{
		this.age = age;
		this.address = new Address(address);
	}
	
	public User clone() 
			throws CloneNotSupportedException
	{
		return (User)super.clone();
	}
}
public class CloneTest {
	public static void main(String[] args)
	        throws CloneNotSupportedException
	{
		String str = "北京海淀";
		User u1 = new User(1,str);
		User u2 = u1.clone();
		System.out.println(u1 == u2);
		System.out.println(u1.address == u2.address);
	}	
} 

每个要调用clone方法的函数必须throws CloneNotSupportedException。


结果输出是

false

true

因为u1和u2在栈中是两个不同的引用变量,当然不相等。而u1创建时,str作为参数传入构造器,而构造器里面用str创建了一个Address类的对象,取名叫A好了,并把u1.address引用到A。u1克隆出u2,u2.address克隆了u1.address的引用(地址),而Address对象还是只有那个A,u2.address同样指向这个A,所以第二个结果当然是true。

这也说明,clone方法是一种“浅克隆”,只克隆对象本身的成员变量,当这个值是一个引用时,并不会克隆引用的对象。如果需要深克隆,则可以用递归实现。

一个值得注意的地方是,clone是一个效率很高的方法,对于一个一百个int的int[]数据类型,clone方法比静态copy方法快接近两倍。(int[] 是一个跟int完全不同的引用类型,它也有方法)。


注意:有两个问题

1、一个类要重写clone方法,必须实现Cloneable接口,本来以为不需要,因为任何一个类都继承自Object,通过super完全可以调用父类的clone方法,为什么一定要实现这个接口呢,反正不实现这个接口就会抛出上面个异常。猜想是接口里面有变量来完成某种判断?

2、书上说自定义类里面要实现自己的clone方法,个人尝试了一下其实User里面的clone方法当然可以取别的名字,一样可以成功运行。但是如果某个子类继承了User,要进行克隆的时候,就必须知道User里克隆的方法是什么,对于程序的扩展是很麻烦的。那么全部都定义为clone,这样无论什么类,只要用super.clone() 就可以一路调用父类的clone方法直到Object,方便多了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值