????我們知道在Java在java中,傳參時,都是以傳值的形式進行。對于基本數據類型,傳遞的是數據的拷貝,對于引用類型,傳遞的引用的拷貝。為了獲取對象的一份拷貝,我們可以利用Object類的clone()方法。至于怎么樣來實現Clone我們必須做以下的事情:
1> 在派生類中覆蓋基類的clone(),并聲明為public。
2> 在派生類的clone()方法中,調用super.clone()。
3> 在派生類中實現Cloneable接口。
4> 沒有抽象方法的接口叫標識接口。
5> 為什么我們在派生類中覆蓋Object的clone()方法時,一定要調用super.clone()呢?在運行時刻,Object
?? 的clone()方法能識別出你要復制的是哪一個對象,然后為此對象分配空間,并進行對象的復制,將原
?? 始對象的內容一一復制到新的對象空間去。
我們看下面的例子:
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;
? ?}
}
運行結果如下:
F:\Java Develop>javac TestClone.java
F:\Java Develop>java TestClone
name=Dog,weight=50
我們看到我們修改an2的值并沒有影響到an1里的值,這就是克隆的作用.是因為在這里通過Clone我們在內存中有2塊地方用來儲存不同的an1,an2
我們在看下面一個例子,我們再增加一個動物的飼養員類,來相關到具體的每個動物.
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;
?}
}
我們看輸出結果:
F:\Java Develop>javac TestClone.java
F:\Java Develop>java TestClone
baidu
60
從結果可以看出來我們修改了an2.f.name和an.f.age但是an1去發生了變化,這是因為我們沒有對Feeder類進行克隆,這就是淺克隆,為了解決這個問題我們需要用到Deeply克隆,java默認的克隆方式是淺克隆.
代碼如下:
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;
?}
}
輸出結果如下:
F:\Java Develop>javac TestClone.java
F:\Java Develop>java TestClone
google
50
java淺克隆是指copy類里所有沒有引用類型的變量.Deeply Clone則剛好相反.