java 對(duì)象的克隆(淺克隆和深克?。?/h1>
更新時(shí)間:2017年07月21日 11:43:25 作者:沈君
這篇文章主要介紹了java 對(duì)象的克隆的相關(guān)資料,這里對(duì)淺克隆和深克隆進(jìn)行了實(shí)例分析需要的朋友可以參考下
java 對(duì)象的克隆
一、對(duì)象的淺克隆
(1)需要克隆類需要重寫Object類的clone方法,并且實(shí)現(xiàn)Cloneable接口(標(biāo)識(shí)接口,無需實(shí)現(xiàn)任何方法)
(2)當(dāng)需要克隆的對(duì)象中維護(hù)著另外一個(gè)引用對(duì)象,淺克隆不會(huì)克隆另外一個(gè)引用對(duì)下,而是直接復(fù)制維護(hù)的另外一個(gè)引用對(duì)象的地址。
(3)對(duì)象的淺克隆也不會(huì)調(diào)用到構(gòu)造方法。
以下為對(duì)象的淺克隆的一個(gè)例子:
package com.clone;
import java.io.Serializable;
/**
* Description:
* 實(shí)現(xiàn)了Cloneable接口,并重寫Object類的clone方法。
*
* @author lee
* */
public class CloneDemo1 implements Cloneable,Serializable{
//該克隆類封裝的信息
public int id;
public String name;
public Address address;
/**
* Desciption:
* 默認(rèn)構(gòu)造器
*
* */
public CloneDemo1(){}
/**
* Description:
* 初始化id,name的構(gòu)造器
*
* @param id id
* @param name 名字
* @param address 地址
* */
public CloneDemo1(int id, String name, Address address){
this.id=id;
this.name=name;
this.address = address;
}
/**
* Descriptin:
* 重寫Object類的clone方法。
* if the object's class does not support the Cloneable interface.
* Subclasses that override the clone method can also throw this exception
* to indicate that an instance cannot be cloned.
*
* @throws CloneNotSupportedException
* */
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
/**
* Description:
* 重寫toString方法
*
* @return "id="+id+", name="+name
* */
@Override
public String toString(){
return "id="+id+", name="+name+", address:"+address.getAddress();
}
/**
* Description:
* 主方法
*
* */
public static void main(String[] args) throws CloneNotSupportedException{
CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));
//c2 復(fù)制了c1的地址,并沒有復(fù)制整個(gè)c1對(duì)象
CloneDemo1 c2 = c1;
//c3 對(duì)象的淺克隆,復(fù)制了整個(gè)對(duì)象
CloneDemo1 c3 = (CloneDemo1)c1.clone();
//當(dāng)對(duì)象c1改變其name或者id的時(shí)候,c2也會(huì)自動(dòng)改變。
//因?yàn)閏2只是復(fù)制了c1的地址,并非復(fù)制了c1的整個(gè)對(duì)象。
//相應(yīng)的c3則不會(huì)隨著c1改變而改變,意味著c3將c1整個(gè)對(duì)象克隆一份出來。
//當(dāng)是,對(duì)象的淺克隆不會(huì)克隆被克隆對(duì)象當(dāng)中的引用對(duì)象。
//因此c1改變其中的Address的引用對(duì)象時(shí),c2,c3也會(huì)跟著改變。
c1.setName("cc");
c1.address.setAddress("上海");
System.out.println(c1+"\n"+c2+"\n"+c3);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* Description:
* 一個(gè)封裝著地址的類
*
* @author lee
* */
class Address implements Serializable{
public String address;
/**
* Description:
* 默認(rèn)構(gòu)造器
*
* */
public Address(){}
/**
* Description:
* 初試化address
*
* @param address 地址
* */
public Address(String address){
this.address = address;
}
//address的set和get方法
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
二、對(duì)象的深克隆
就是利用對(duì)象的輸入輸出流把對(duì)象寫到文件上,再讀取對(duì)象的信息,這就是對(duì)象的深克隆。
由于對(duì)象的淺克隆不會(huì)克隆被克隆對(duì)象其中的引用對(duì)象,而是直接復(fù)制其地址。因此,要克隆被克隆對(duì)象當(dāng)中的引用類型則需要對(duì)象的深克隆。
而對(duì)象的深克隆使用的的對(duì)象序列化輸入輸出。
代碼如下:
package com.clone;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Description:
* 實(shí)現(xiàn)對(duì)象的深克隆
*
* @author lee
* */
public class CloneDemo2 {
/**
* Description:
* 將對(duì)象輸出到一個(gè)文件當(dāng)中。
*
* @param c 需要被寫到文件當(dāng)中的對(duì)象。
* */
public static void writeObject(CloneDemo1 c){
ObjectOutputStream out = null;
try{
//將對(duì)象輸出在一個(gè)object.txt文件當(dāng)中
out = new ObjectOutputStream(new FileOutputStream("./object.txt"));
out.writeObject(c);
}catch(IOException e){
System.out.println("寫入對(duì)象的時(shí)候發(fā)生了錯(cuò)誤。");
e.printStackTrace();
}finally{
//關(guān)閉資源
try{
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
/**
* Description:
* 從文件中讀取出一個(gè)對(duì)象來,并返回。
*
* @return c 返回一個(gè)對(duì)象。
* */
public static CloneDemo1 readObject(){
CloneDemo1 c = null;
ObjectInputStream input = null;
try{
//從object.txt文件中讀取一個(gè)對(duì)象出來
input = new ObjectInputStream(new FileInputStream("./object.txt"));
c = (CloneDemo1)input.readObject();
}catch(IOException | ClassNotFoundException e){
e.printStackTrace();
System.out.println("讀取對(duì)象的時(shí)候發(fā)生了錯(cuò)誤。");
}finally{
//關(guān)閉資源
try{
input.close();
}catch(IOException e){
e.printStackTrace();
}
}
return c;
}
/**
* Description:
* 主方法
*
* @throws CloneNotSupportedException
* */
public static void main(String[] args) throws CloneNotSupportedException {
CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));
//c2 對(duì)象的淺克隆
CloneDemo1 c2 = (CloneDemo1)c1.clone();
//c3對(duì)象的深克隆
writeObject(c1);
CloneDemo1 c3 = readObject();
//因?yàn)閷?duì)象的深克隆同時(shí)也克隆了被克隆對(duì)象維護(hù)的另外一個(gè)對(duì)象
//所以,當(dāng)c1改變其當(dāng)中的維護(hù)的另外一個(gè)對(duì)象的時(shí)候,c3不會(huì)隨之改變。
//而c2位淺克隆,其維護(hù)的另外一個(gè)對(duì)象只是復(fù)制了c1維護(hù)的對(duì)象的地址,因此會(huì)隨著c1的改變而改變。
c1.address.setAddress("上海");
System.out.println(c1+"\n"+c2+"\n"+c3);
}
}
對(duì)象的序列化,是需要實(shí)現(xiàn)Serializable接口的。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
-
IDEA新建Springboot項(xiàng)目(圖文教程)
下面小編就為大家?guī)硪黄狪DEA新建Springboot項(xiàng)目(圖文教程)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧 2017-07-07
-
springboot 配置文件配置項(xiàng)前綴為0的數(shù)字特殊處理方式
這篇文章主要介紹了springboot 配置文件配置項(xiàng)前綴為0的數(shù)字特殊處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2022-02-02
-
java讀取html文件,并獲取body中所有的標(biāo)簽及內(nèi)容的案例
這篇文章主要介紹了java讀取html文件,并獲取body中所有的標(biāo)簽及內(nèi)容的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 2020-08-08
最新評(píng)論
java 對(duì)象的克隆
一、對(duì)象的淺克隆
(1)需要克隆類需要重寫Object類的clone方法,并且實(shí)現(xiàn)Cloneable接口(標(biāo)識(shí)接口,無需實(shí)現(xiàn)任何方法)
(2)當(dāng)需要克隆的對(duì)象中維護(hù)著另外一個(gè)引用對(duì)象,淺克隆不會(huì)克隆另外一個(gè)引用對(duì)下,而是直接復(fù)制維護(hù)的另外一個(gè)引用對(duì)象的地址。
(3)對(duì)象的淺克隆也不會(huì)調(diào)用到構(gòu)造方法。
以下為對(duì)象的淺克隆的一個(gè)例子:
package com.clone;
import java.io.Serializable;
/**
* Description:
* 實(shí)現(xiàn)了Cloneable接口,并重寫Object類的clone方法。
*
* @author lee
* */
public class CloneDemo1 implements Cloneable,Serializable{
//該克隆類封裝的信息
public int id;
public String name;
public Address address;
/**
* Desciption:
* 默認(rèn)構(gòu)造器
*
* */
public CloneDemo1(){}
/**
* Description:
* 初始化id,name的構(gòu)造器
*
* @param id id
* @param name 名字
* @param address 地址
* */
public CloneDemo1(int id, String name, Address address){
this.id=id;
this.name=name;
this.address = address;
}
/**
* Descriptin:
* 重寫Object類的clone方法。
* if the object's class does not support the Cloneable interface.
* Subclasses that override the clone method can also throw this exception
* to indicate that an instance cannot be cloned.
*
* @throws CloneNotSupportedException
* */
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
/**
* Description:
* 重寫toString方法
*
* @return "id="+id+", name="+name
* */
@Override
public String toString(){
return "id="+id+", name="+name+", address:"+address.getAddress();
}
/**
* Description:
* 主方法
*
* */
public static void main(String[] args) throws CloneNotSupportedException{
CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));
//c2 復(fù)制了c1的地址,并沒有復(fù)制整個(gè)c1對(duì)象
CloneDemo1 c2 = c1;
//c3 對(duì)象的淺克隆,復(fù)制了整個(gè)對(duì)象
CloneDemo1 c3 = (CloneDemo1)c1.clone();
//當(dāng)對(duì)象c1改變其name或者id的時(shí)候,c2也會(huì)自動(dòng)改變。
//因?yàn)閏2只是復(fù)制了c1的地址,并非復(fù)制了c1的整個(gè)對(duì)象。
//相應(yīng)的c3則不會(huì)隨著c1改變而改變,意味著c3將c1整個(gè)對(duì)象克隆一份出來。
//當(dāng)是,對(duì)象的淺克隆不會(huì)克隆被克隆對(duì)象當(dāng)中的引用對(duì)象。
//因此c1改變其中的Address的引用對(duì)象時(shí),c2,c3也會(huì)跟著改變。
c1.setName("cc");
c1.address.setAddress("上海");
System.out.println(c1+"\n"+c2+"\n"+c3);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* Description:
* 一個(gè)封裝著地址的類
*
* @author lee
* */
class Address implements Serializable{
public String address;
/**
* Description:
* 默認(rèn)構(gòu)造器
*
* */
public Address(){}
/**
* Description:
* 初試化address
*
* @param address 地址
* */
public Address(String address){
this.address = address;
}
//address的set和get方法
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
二、對(duì)象的深克隆
就是利用對(duì)象的輸入輸出流把對(duì)象寫到文件上,再讀取對(duì)象的信息,這就是對(duì)象的深克隆。
由于對(duì)象的淺克隆不會(huì)克隆被克隆對(duì)象其中的引用對(duì)象,而是直接復(fù)制其地址。因此,要克隆被克隆對(duì)象當(dāng)中的引用類型則需要對(duì)象的深克隆。
而對(duì)象的深克隆使用的的對(duì)象序列化輸入輸出。
代碼如下:
package com.clone;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Description:
* 實(shí)現(xiàn)對(duì)象的深克隆
*
* @author lee
* */
public class CloneDemo2 {
/**
* Description:
* 將對(duì)象輸出到一個(gè)文件當(dāng)中。
*
* @param c 需要被寫到文件當(dāng)中的對(duì)象。
* */
public static void writeObject(CloneDemo1 c){
ObjectOutputStream out = null;
try{
//將對(duì)象輸出在一個(gè)object.txt文件當(dāng)中
out = new ObjectOutputStream(new FileOutputStream("./object.txt"));
out.writeObject(c);
}catch(IOException e){
System.out.println("寫入對(duì)象的時(shí)候發(fā)生了錯(cuò)誤。");
e.printStackTrace();
}finally{
//關(guān)閉資源
try{
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
/**
* Description:
* 從文件中讀取出一個(gè)對(duì)象來,并返回。
*
* @return c 返回一個(gè)對(duì)象。
* */
public static CloneDemo1 readObject(){
CloneDemo1 c = null;
ObjectInputStream input = null;
try{
//從object.txt文件中讀取一個(gè)對(duì)象出來
input = new ObjectInputStream(new FileInputStream("./object.txt"));
c = (CloneDemo1)input.readObject();
}catch(IOException | ClassNotFoundException e){
e.printStackTrace();
System.out.println("讀取對(duì)象的時(shí)候發(fā)生了錯(cuò)誤。");
}finally{
//關(guān)閉資源
try{
input.close();
}catch(IOException e){
e.printStackTrace();
}
}
return c;
}
/**
* Description:
* 主方法
*
* @throws CloneNotSupportedException
* */
public static void main(String[] args) throws CloneNotSupportedException {
CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));
//c2 對(duì)象的淺克隆
CloneDemo1 c2 = (CloneDemo1)c1.clone();
//c3對(duì)象的深克隆
writeObject(c1);
CloneDemo1 c3 = readObject();
//因?yàn)閷?duì)象的深克隆同時(shí)也克隆了被克隆對(duì)象維護(hù)的另外一個(gè)對(duì)象
//所以,當(dāng)c1改變其當(dāng)中的維護(hù)的另外一個(gè)對(duì)象的時(shí)候,c3不會(huì)隨之改變。
//而c2位淺克隆,其維護(hù)的另外一個(gè)對(duì)象只是復(fù)制了c1維護(hù)的對(duì)象的地址,因此會(huì)隨著c1的改變而改變。
c1.address.setAddress("上海");
System.out.println(c1+"\n"+c2+"\n"+c3);
}
}
對(duì)象的序列化,是需要實(shí)現(xiàn)Serializable接口的。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
IDEA新建Springboot項(xiàng)目(圖文教程)
下面小編就為大家?guī)硪黄狪DEA新建Springboot項(xiàng)目(圖文教程)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
springboot 配置文件配置項(xiàng)前綴為0的數(shù)字特殊處理方式
這篇文章主要介紹了springboot 配置文件配置項(xiàng)前綴為0的數(shù)字特殊處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
java讀取html文件,并獲取body中所有的標(biāo)簽及內(nèi)容的案例
這篇文章主要介紹了java讀取html文件,并獲取body中所有的標(biāo)簽及內(nèi)容的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08

