????我們知道在Java在java中,傳參時(shí),都是以傳值的形式進(jìn)行。對(duì)于基本數(shù)據(jù)類型,傳遞的是數(shù)據(jù)的拷貝,對(duì)于引用類型,傳遞的引用的拷貝。為了獲取對(duì)象的一份拷貝,我們可以利用Object類的clone()方法。至于怎么樣來(lái)實(shí)現(xiàn)Clone我們必須做以下的事情:
1> 在派生類中覆蓋基類的clone(),并聲明為public。
2> 在派生類的clone()方法中,調(diào)用super.clone()。
3> 在派生類中實(shí)現(xiàn)Cloneable接口。
4> 沒(méi)有抽象方法的接口叫標(biāo)識(shí)接口。
5> 為什么我們?cè)谂缮愔懈采wObject的clone()方法時(shí),一定要調(diào)用super.clone()呢?在運(yùn)行時(shí)刻,Object
?? 的clone()方法能識(shí)別出你要復(fù)制的是哪一個(gè)對(duì)象,然后為此對(duì)象分配空間,并進(jìn)行對(duì)象的復(fù)制,將原
?? 始對(duì)象的內(nèi)容一一復(fù)制到新的對(duì)象空間去。
我們看下面的例子:
class TestClone
{
?public static void main(String[] args)
? ?{
????? Animal an1=new Animal("Dog",50);
???? ?Animal an2=(Animal)an1.clone();
??????an2.name="Fox";
??? ??an2.weight=30;
???? ?System.out.println(an1);
?? ?}
}
class Animal implements Cloneable
{
?? String name;
?? int weight;
?public Animal(String name,int weight)
?? {
?????? this.name=name;
???? ? this.weight=weight;
?? }
?public String toString()
? {
????? ?return "name="+name+","+"weight="+weight;
? }
?public Object clone()
??{
???? Object o=null;
??try
?? ?{
????? ?o=super.clone();
??? ?}
??catch(CloneNotSupportedException e)
??{
?????? System.out.println(e.toString());
??}
???? ?return o;
? ?}
}
運(yùn)行結(jié)果如下:
F:\Java Develop>javac TestClone.java
F:\Java Develop>java TestClone
name=Dog,weight=50
我們看到我們修改an2的值并沒(méi)有影響到an1里的值,這就是克隆的作用.是因?yàn)樵谶@里通過(guò)Clone我們?cè)趦?nèi)存中有2塊地方用來(lái)儲(chǔ)存不同的an1,an2
我們?cè)诳聪旅嬉粋€(gè)例子,我們?cè)僭黾右粋€(gè)動(dòng)物的飼養(yǎng)員類,來(lái)相關(guān)到具體的每個(gè)動(dòng)物.
class TestClone
{
?public static void main(String[] args)
?{
??Feeder f=new Feeder("google",50);
??Animal an1=new Animal("Dog",50,f);
??Animal an2=(Animal)an1.clone();
??an2.f.name="baidu";
??an2.f.age=60;
??System.out.println(an1.f.name);
??System.out.println(an1.f.age);
?}
}
/*
class Feeder implements Cloneable
{
?String name;
?int age;
?public Feeder(String name,int age)
?{
??this.name=name;
??this.age=age;
?}
?public Object clone()
?{
??Object o=null;
??try
??{
???o=super.clone();
??}
??catch(CloneNotSupportedException e)
??{
???System.out.println(e.toString());
??}
??return o;
?}
}
*/
class Feeder
{
?String name;
?int age;
?public Feeder(String name,int age)
?{
??this.name=name;
??this.age=age;
?}
}
class Animal implements Cloneable
{
?String name;
?int weight;
?Feeder f;
?public Animal(String name,int weight,Feeder f)
?{
??this.name=name;
??this.weight=weight;
??this.f=f;
?}
?public String toString()
?{
??return "name="+name+","+"weight="+weight;
?}
?public Object clone()
?{
??Object o=null;
??//Animal o=null;
??try
??{
???o=super.clone();
??}
??catch(CloneNotSupportedException e)
??{
???System.out.println(e.toString());
??}
??//o.f=(Feeder)f.clone();
??return o;
?}
}
我們看輸出結(jié)果:
F:\Java Develop>javac TestClone.java
F:\Java Develop>java TestClone
baidu
60
從結(jié)果可以看出來(lái)我們修改了an2.f.name和an.f.age但是an1去發(fā)生了變化,這是因?yàn)槲覀儧](méi)有對(duì)Feeder類進(jìn)行克隆,這就是淺克隆,為了解決這個(gè)問(wèn)題我們需要用到Deeply克隆,java默認(rèn)的克隆方式是淺克隆.
代碼如下:
class TestClone
{
?public static void main(String[] args)
?{
??Feeder f=new Feeder("google",50);
??Animal an1=new Animal("Dog",50,f);
??Animal an2=(Animal)an1.clone();
??an2.f.name="baidu";
??an2.f.age=60;
??System.out.println(an1.f.name);
??System.out.println(an1.f.age);
?}
}
class Feeder implements Cloneable
{
?String name;
?int age;
?public Feeder(String name,int age)
?{
??this.name=name;
??this.age=age;
?}
?public Object clone()
?{
??Object o=null;
??try
??{
???o=super.clone();
??}
??catch(CloneNotSupportedException e)
??{
???System.out.println(e.toString());
??}
??return o;
?}
}
class Animal implements Cloneable
{
?String name;
?int weight;
?Feeder f;
?public Animal(String name,int weight,Feeder f)
?{
??this.name=name;
??this.weight=weight;
??this.f=f;
?}
?public String toString()
?{
??return "name="+name+","+"weight="+weight;
?}
?public Object clone()
?{
??//Object o=null;
??Animal o=null;
??try
??{
???o=(Animal)super.clone();
??}
??catch(CloneNotSupportedException e)
??{
???System.out.println(e.toString());
??}
??o.f=(Feeder)f.clone();
??return o;
?}
}
輸出結(jié)果如下:
F:\Java Develop>javac TestClone.java
F:\Java Develop>java TestClone
google
50
java淺克隆是指copy類里所有沒(méi)有引用類型的變量.Deeply Clone則剛好相反.