// ----------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())); //相同?
-- 以上如果有错,欢迎指出。