搜尋
首頁JavaJava面試題談談你對java中的深克隆和淺克隆的理解

談談你對java中的深克隆和淺克隆的理解

阿里面試官問題:

談談你對java中的深克隆和淺克隆的理解

回答:

#(說明:本文針對深克隆和淺克隆的區別和實現方式?這個問題)

Talk is cheap

#最近不只一次遇見深淺克隆(深複製,淺複製)的問題,除了印像中有個clone方法外一臉懵逼! ! !克隆(複製)在Java中是一種常見的操作,目的是快速取得一個物件副本。克隆分為深克隆和淺克隆。

淺克隆:建立一個新對象,新對象的屬性和原來對象完全相同,對於非基本型別屬性,仍指向原有屬性所指向的對象的​​記憶體位址。

深克隆:建立一個新對象,屬性中引用的其他對像也會被克隆,不再指向原有對象位址。

總之深淺克隆都會在堆中新分配一塊區域,差異在於物件屬性所引用的物件是否需要進行複製(遞歸性的)。

Show you my picture

#pos:目前物件的位址;

son:son屬性所指向的位址;

name:物件的name屬性。

談談你對java中的深克隆和淺克隆的理解

(相關推薦:java入門教學

Show you my code

#case1:

public class Son implements Serializable , Cloneable{    private String name;    private Son son;    public Son() {        super();
    }    public String getName() {        return name;
    }    public void setName(String name) {        this.name = name;
    }    public Son getSon() {        return son;
    }    public void setSon(Son son) {        this.son = son;
    }    @Override
    public String toString() {        return super.toString();
    }    @Override
    protected Object clone() throws CloneNotSupportedException {        return super.clone();
    }
}

測試

public static void main(String[] args) throws Exception{	// 创建父亲(LiLiu),儿子(LiWu),孙子(LiLiu)并关联
	Son father = new Son();
	father.setName("LiSi");
	Son son = new Son();
	son.setName("LiWu");
	Son grandSon = new Son();
	grandSon.setName("LiLiu");
	father.setSon(son);
	son.setSon(grandSon);	// 调用clone方法
	Son fatherCopy =  (Son) father.clone();	boolean flag1 = fatherCopy==father;	boolean flag2 = fatherCopy.getSon() == son;	boolean flag3 = fatherCopy.getSon().getSon() == grandSon;	// 比较克隆后的地址
	System.out.println(flag1);// false
	System.out.println(flag2);// true
	System.out.println(flag3);// true
	// 比较Name
	flag1= fatherCopy.getName()==father.getName();
	flag2 = fatherCopy.getSon().getName() == son.getName();
	flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();
	System.out.println(flag1);// true
	System.out.println(flag2);// true
	System.out.println(flag3);// true
	
	//将对象写到流里    
	ByteArrayOutputStream byteOut=new ByteArrayOutputStream();    
	ObjectOutputStream objOut=new ObjectOutputStream(byteOut);    
	objOut.writeObject(father);	//从流里读出来    
	ByteArrayInputStream byteIn=new ByteArrayInputStream(byteOut.toByteArray());    
	ObjectInputStream objInput=new ObjectInputStream(byteIn);
    fatherCopy = (Son) objInput.readObject();
	flag1= fatherCopy==father;
	flag2 = fatherCopy.getSon() == son;
	flag3 = fatherCopy.getSon().getSon() == grandSon;
	System.out.println(flag1);// false
	System.out.println(flag2);// false
	System.out.println(flag3);// false
	
	// 比较Name
	flag1= fatherCopy.getName()==father.getName();
	flag2 = fatherCopy.getSon().getName() == son.getName();
	flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();
	System.out.println(flag1);// false
	System.out.println(flag2);// false
	System.out.println(flag3);// false}

從上文程式碼及運行結果不難看出,如果物件實作Cloneable並重寫clone方法不進行任何操作時,呼叫clone是進行的淺克隆。而使用物件流將物件寫入流然後再讀出是進行的深克隆。

思考:既然實作Cloneable介面並重寫clone介面只能進行淺克隆。但如果類別的參考型別屬性(以及屬性的參考型別屬性)都進行淺克隆,直到沒有引用型別屬性或引用型別屬性為null時,整體上就形成了深克隆。既物件的參考型別屬性和屬性的應用型別屬性都實作Coloneable,重寫clone方法並在clone方法中進行呼叫。

protected Object clone() throws CloneNotSupportedException {
      Son result = (Son) super.clone();	if (son != null) {
		result.son = (Son) son.clone();
	}    return result;
}

個人認為,在選擇深克隆方法時,應根據物件的複雜程度,如引用類型屬性是否有多層引用類型屬性關係。若物件只有一層或兩層引用類型的屬性,選擇思考中所提到的方法較為方便,反之則使用物件流。

更多相關面試題請上:java面試題目及答案

以上是談談你對java中的深克隆和淺克隆的理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),