// ----------1、直接復制對象 -----------
package ninthTestModel;
/*
* 淺克隆
* 深克隆
* 序列化。
* 區別在于對象有引用對象的時候 一個是指向同一個引用對象 一個是指向不同對象
*/
/*
*
* 【淺克隆】,通常只是對克隆的實例進行復制,但里面的其他子對象,都是共用的。
* 【深克隆】,克隆的時候會復制它的子對象的引用,里面所有的變量和子對象都是又額外拷貝了一份。
*
*/
// 周報
class WeekdayInformation{
public String strInformation; // 事件
public String strTime; // 時間
public String strLocation; // 地點
public String getStrInformation() {
return strInformation;
}
public String getStrTime() {
return strTime;
}
public String getStrLocation() {
return strLocation;
}
public void setStrInformation(String strInformation) {
this.strInformation = strInformation;
}
public void setStrTime(String strTime) {
this.strTime = strTime;
}
public void setStrLocation(String strLocation) {
this.strLocation = strLocation;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "事件:"+strInformation+"\t時間:"+strTime+"\t地點:"+strLocation;
}
}
public class CloneModel {
public static void main(String[] args) {
// TODO Auto-generated method stub
WeekdayInformation weekdayInformation=new WeekdayInformation();
weekdayInformation.setStrInformation("吃飯");
weekdayInformation.setStrTime("周一");
weekdayInformation.setStrLocation("食堂");
System.out.println(weekdayInformation.toString()); // ninthTestModel.WeekdayInformation@2a139a55
WeekdayInformation week2=weekdayInformation;
System.out.println(week2.toString());
System.out.println("***********************");
/*
* weekdayInformation修改信息 則week2的信息也修改
*/
System.out.println("weekdayInformation修改了信息:");
weekdayInformation.setStrTime("周二");
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
System.out.println("***********************");
/*
* week2修改信息 則weekdayInformation的信息也修改
*/
System.out.println("week2修改了信息:");
week2.setStrTime("周一");
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
}
}
/*
結果如下:
事件:吃飯 時間:周一 地點:食堂
事件:吃飯 時間:周一 地點:食堂
***********************
weekdayInformation修改了信息:
事件:吃飯 時間:周二 地點:食堂
事件:吃飯 時間:周二 地點:食堂
***********************
week2修改了信息:
事件:吃飯 時間:周一 地點:食堂
事件:吃飯 時間:周一 地點:食堂
*/
// --------2、淺克隆 里面沒有引用對象---
package ninthTestModel;
/*
* 淺克隆
* 深克隆
* 序列化。
* 區別在于對象有引用對象的時候 一個是指向同一個引用對象 一個是指向不同對象
*/
/*
*
* 【淺克隆】,通常只是對克隆的實例進行復制,但里面的其他子對象,都是共用的。
* 【深克隆】,克隆的時候會復制它的子對象的引用,里面所有的變量和子對象都是又額外拷貝了一份。
*
*/
// 周報
class WeekdayInformation implements Cloneable{
public String strInformation; // 事件
public String strTime; // 時間
public String strLocation; // 地點
public String getStrInformation() {
return strInformation;
}
public String getStrTime() {
return strTime;
}
public String getStrLocation() {
return strLocation;
}
public void setStrInformation(String strInformation) {
this.strInformation = strInformation;
}
public void setStrTime(String strTime) {
this.strTime = strTime;
}
public void setStrLocation(String strLocation) {
this.strLocation = strLocation;
}
// 淺克隆
@Override
protected WeekdayInformation clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Object object=null;
object=super.clone();
System.out.println("淺克隆");
return (WeekdayInformation) object;
// TODO Auto-generated catch block
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "事件:"+strInformation+"\t時間:"+strTime+"\t地點:"+strLocation;
}
}
public class CloneModel {
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
WeekdayInformation weekdayInformation=new WeekdayInformation();
weekdayInformation.setStrInformation("吃飯");
weekdayInformation.setStrTime("周一");
weekdayInformation.setStrLocation("食堂");
System.out.println(weekdayInformation.toString()); // ninthTestModel.WeekdayInformation@2a139a55
WeekdayInformation week2=weekdayInformation.clone();
System.out.println(week2.toString());
System.out.println("***********************");
/*
* weekdayInformation修改信息 則week2的信息也修改
*/
System.out.println("weekdayInformation修改了信息:");
weekdayInformation.setStrTime("周二。");
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
System.out.println("***********************");
/*
* week2修改信息 則weekdayInformation的信息也修改
*/
System.out.println("week2修改了信息:");
week2.setStrTime("周三。");
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
}
}
結果如下:
/*
事件:吃飯 時間:周一 地點:食堂
淺克隆
事件:吃飯 時間:周一 地點:食堂
***********************
weekdayInformation修改了信息:
事件:吃飯 時間:周二。 地點:食堂
事件:吃飯 時間:周一 地點:食堂
***********************
week2修改了信息:
事件:吃飯 時間:周二。 地點:食堂
事件:吃飯 時間:周三。 地點:食堂
*/
// ----------3、淺克隆 里面有被引用對象
package ninthTestModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.Serializable;
import sixTestOop.TestEighthToString;
/*
* 淺克隆
* 深克隆
* 序列化。
* 區別在于對象有引用對象的時候 一個是指向同一個引用對象 一個是指向不同對象
*/
/*
*
* 【淺克隆】,通常只是對克隆的實例進行復制,但里面的其他子對象,都是共用的。
* 【深克隆】,克隆的時候會復制它的子對象的引用,里面所有的變量和子對象都是又額外拷貝了一份。
* 注:!序列化問題 因為使用了序列化方法實現深克隆 因此類需要繼承Serializable 引用類也需要繼承
*/
class TestClone implements Serializable{
public String testString;
public void setTestString(String testString) {
this.testString = testString;
}
public String getTestString() {
return testString;
}
}
// 周報
class WeekdayInformation implements Cloneable,Serializable{
public String strInformation; // 事件
public String strTime; // 時間
public String strLocation; // 地點
public TestClone strClone; // 被引用對象
public String getStrInformation() {
return strInformation;
}
public String getStrTime() {
return strTime;
}
public String getStrLocation() {
return strLocation;
}
public TestClone getStrClone() {
return strClone;
}
public void setStrInformation(String strInformation) {
this.strInformation = strInformation;
}
public void setStrTime(String strTime) {
this.strTime = strTime;
}
public void setStrLocation(String strLocation) {
this.strLocation = strLocation;
}
public void setStrClone(TestClone strClone) {
this.strClone = strClone;
}
// 淺克隆
@Override
protected WeekdayInformation clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Object object=null;
object=super.clone();
System.out.println("淺克隆");
return (WeekdayInformation) object;
}
// 深克隆
public WeekdayInformation deepClone() throws IOException, ClassNotFoundException,OptionalDataException {
System.out.println("******深克隆*********\n");
WeekdayInformation weekdayInformation=null;
// -- 將對象寫入流中
ByteArrayOutputStream bao=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao);
oos.writeObject(this);
oos.close();
// -- 將對象從流中取出
ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
weekdayInformation=(WeekdayInformation) ois.readObject();
ois.close();
return weekdayInformation;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "事件:"+strInformation+"\t時間:"+strTime+"\t地點:"+strLocation+"\t測試:"+strClone.getTestString();
}
}
public class CloneModel {
public static void main(String[] args) throws CloneNotSupportedException, OptionalDataException, ClassNotFoundException, IOException {
// TODO Auto-generated method stub
WeekdayInformation weekdayInformation=new WeekdayInformation();
TestClone testClone=new TestClone();
testClone.setTestString("test");
weekdayInformation.setStrInformation("吃飯");
weekdayInformation.setStrTime("周一");
weekdayInformation.setStrLocation("食堂");
weekdayInformation.setStrClone(testClone);
System.out.println(weekdayInformation.toString()); //如果沒重寫toString()方法顯示: ninthTestModel.WeekdayInformation@2a139a55
WeekdayInformation week2 = weekdayInformation.clone();
System.out.println("克隆信息如下:"+week2+"\n");
System.out.println("克隆對象是否相同:"+(weekdayInformation==week2));//
//?? 為什么兩個都相同了?? 因為指向的同一個對象
System.out.println("被引用對象TestClone是否相同:"+(weekdayInformation.getStrClone()==week2.getStrClone())); //相同? --相同
System.out.println("基本對象String是否相同:"+(weekdayInformation.getStrInformation()==week2.getStrInformation())); //相同? -- 相同
System.out.println("***********\n");
System.out.println(week2.toString());
System.out.println("***********************");
/*
* weekdayInformation修改信息 則week2的信息也修改
*/
TestClone testClone1=new TestClone();
testClone1.setTestString("test1");
System.out.println("weekdayInformation修改了信息:");
weekdayInformation.setStrTime("周二");
weekdayInformation.setStrClone(testClone1);
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
System.out.println("***********************");
/*
* week2修改信息 則weekdayInformation的信息也修改
*/
TestClone testClone2=new TestClone();
testClone2.setTestString("test2");
System.out.println("week2修改了信息:");
week2.setStrTime("周三");
week2.setStrClone(testClone2);
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
}
}
/*
輸出結果如下:
事件:吃飯 時間:周一 地點:食堂 測試:test
淺克隆
克隆信息如下:事件:吃飯 時間:周一 地點:食堂 測試:test
克隆對象是否相同:false
被引用對象TestClone是否相同:true
基本對象String是否相同:true
***********
事件:吃飯 時間:周一 地點:食堂 測試:test
***********************
weekdayInformation修改了信息:
事件:吃飯 時間:周二 地點:食堂 測試:test1
事件:吃飯 時間:周一 地點:食堂 測試:test
***********************
week2修改了信息:
事件:吃飯 時間:周二 地點:食堂 測試:test1
事件:吃飯 時間:周三 地點:食堂 測試:test2
*/
// -----------4、深克隆 里面有被引用對象----------
package ninthTestModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import sixTestOop.TestEighthToString;
/*
* 淺克隆
* 深克隆
* 序列化。
* 區別在于對象有引用對象的時候 一個是指向同一個引用對象 一個是指向不同對象
*/
/*
*
* 【淺克隆】,通常只是對克隆的實例進行復制,但里面的其他子對象,都是共用的。
* 【深克隆】,克隆的時候會復制它的子對象的引用,里面所有的變量和子對象都是又額外拷貝了一份。
*
*/
class TestClone{
public String testString;
public void setTestString(String testString) {
this.testString = testString;
}
public String getTestString() {
return testString;
}
}
// 周報
class WeekdayInformation implements Cloneable{
public String strInformation; // 事件
public String strTime; // 時間
public String strLocation; // 地點
public TestClone strClone; // 被引用對象
public String getStrInformation() {
return strInformation;
}
public String getStrTime() {
return strTime;
}
public String getStrLocation() {
return strLocation;
}
public TestClone getStrClone() {
return strClone;
}
public void setStrInformation(String strInformation) {
this.strInformation = strInformation;
}
public void setStrTime(String strTime) {
this.strTime = strTime;
}
public void setStrLocation(String strLocation) {
this.strLocation = strLocation;
}
public void setStrClone(TestClone strClone) {
this.strClone = strClone;
}
// 淺克隆
@Override
protected WeekdayInformation clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Object object=null;
object=super.clone();
System.out.println("淺克隆");
return (WeekdayInformation) object;
}
// 深克隆
public WeekdayInformation deepClone() throws IOException, ClassNotFoundException {
// -- 將對象寫入流中
ByteArrayOutputStream bao=new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao);
oos.writeObject(this);
// -- 將對象從流中取出
ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
return (WeekdayInformation) ois.readObject();
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "事件:"+strInformation+"\t時間:"+strTime+"\t地點:"+strLocation+"\t測試:"+strClone.getTestString();
}
}
public class CloneModel {
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
WeekdayInformation weekdayInformation=new WeekdayInformation();
TestClone testClone=new TestClone();
testClone.setTestString("test");
weekdayInformation.setStrInformation("吃飯");
weekdayInformation.setStrTime("周一");
weekdayInformation.setStrLocation("食堂");
weekdayInformation.setStrClone(testClone);
System.out.println(weekdayInformation.toString()); // 如果沒有重寫toString()方法會顯示:ninthTestModel.WeekdayInformation@2a139a55
WeekdayInformation week2=weekdayInformation.deepClone();// 這里調用深克隆實現
System.out.println("被引用對象是否相同:"+(weekdayInformation.getStrClone()==week2.getStrClone())); //相同? 不同
System.out.println("是否相同:"+(weekdayInformation.getStrInformation()==week2.getStrInformation())); //相同? 不同
System.out.println(week2.toString());
System.out.println("***********************");
/*
* weekdayInformation修改信息 則week2的信息也修改
*/
TestClone testClone1=new TestClone();
testClone1.setTestString("test1");
System.out.println("weekdayInformation修改了信息:");
weekdayInformation.setStrTime("周二");
weekdayInformation.setStrClone(testClone1);
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
System.out.println("***********************");
/*
* week2修改信息 則weekdayInformation的信息也修改
*/
TestClone testClone2=new TestClone();
testClone2.setTestString("test2");
System.out.println("week2修改了信息:");
week2.setStrTime("周三");
week2.setStrClone(testClone2);
System.out.println(weekdayInformation.toString());
System.out.println(week2.toString());
}
}
/*
輸出結果如下:
事件:吃飯 時間:周一 地點:食堂 測試:test
淺克隆
克隆信息如下:事件:吃飯 時間:周一 地點:食堂 測試:test
克隆對象是否相同:false
被引用對象TestClone是否相同:true
基本對象String是否相同:true
***********
事件:吃飯 時間:周一 地點:食堂 測試:test
***********************
weekdayInformation修改了信息:
事件:吃飯 時間:周二 地點:食堂 測試:test1
事件:吃飯 時間:周一 地點:食堂 測試:test
***********************
week2修改了信息:
事件:吃飯 時間:周二 地點:食堂 測試:test1
事件:吃飯 時間:周三 地點:食堂 測試:test2
*/
自我理解:
對象一 對象二=對象一的復制/淺克隆/深克隆
復制:對象一=對象二 二者完全值得同一個 如果對象一修改 對象二則跟著修改
淺克隆:對象一、二不同,但是對于被引用對象指向的會是同一個對象,
深克隆:對象一、二不同,是完全的創建出了一個新的對象,
對于被引用對象也不同,如這里我所用到的引用對象testClone。
問題:
但是有個問題我沒搞懂,淺克隆的時候為什么String類型的對象也指向的同一個?
也就是在例子三中
被引用對象TestClone是否相同:true //--這個應該是true
基本對象String是否相同:true //-- 這個不應該是false嘛?怎么回事true
源碼:
System.out.println("被引用對象TestClone是否相同:"+(weekdayInformation.getStrClone()==week2.getStrClone())); //相同?
System.out.println("基本對象String是否相同:"+(weekdayInformation.getStrInformation()==week2.getStrInformation())); //相同?
-- 以上如果有錯,歡迎指出。