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

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

Jan 30, 2021 am 09:53 AM
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工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Laravel Lazy Loading與急切的加載 Laravel Lazy Loading與急切的加載 Jul 28, 2025 am 04:23 AM

懶加載在訪問關聯時才查詢,易導致N 1問題,適合不確定是否需要關聯數據的場景;2.急加載使用with()提前加載關聯數據,避免N 1查詢,適合批量處理場景;3.應優先使用急加載優化性能,可通過LaravelDebugbar等工具檢測N 1問題,並謹慎使用模型的$with屬性以避免不必要的性能開銷。

Python內存管理示例 Python內存管理示例 Jul 28, 2025 am 01:10 AM

Python的內存管理基於引用計數和垃圾回收機制,1.引用計數機制確保對像在引用數為0時立即釋放,sys.getrefcount()返回值比實際引用多1因其自身增加引用;2.循環引用無法通過引用計數清理,需依賴gc模塊的分代回收,調用gc.collect()可回收不可達對象;3.實際開發中應避免長期持有大對象引用,可使用weakref弱引用、及時置None釋放內存,並利用tracemalloc監控內存分配;4.總結:Python結合引用計數與垃圾回收管理內存,開發者可通過合理使用工具和優化引用管

將PHP與機器學習模型集成 將PHP與機器學習模型集成 Jul 28, 2025 am 04:37 AM

usearestapitobridgephpandmlmodelsbyrunningthemodelinpythonviaflaskorfastapiandcallingitfromphpusingcurlorguzzle.2.runpythonscriptsdirectsdirectlyectlyectlyfromphpsingexec()orshell_exec()orshell_exec()orshell_exec()

Laravel Raw SQL查詢示例 Laravel Raw SQL查詢示例 Jul 29, 2025 am 02:59 AM

Laravel支持使用原生SQL查詢,但應優先使用參數綁定以確保安全;1.使用DB::select()執行帶參數綁定的SELECT查詢,防止SQL注入;2.使用DB::update()執行UPDATE操作並返回影響行數;3.使用DB::insert()插入數據;4.使用DB::delete()刪除數據;5.使用DB::statement()執行如CREATE、ALTER等無結果集的SQL語句;6.推薦在QueryBuilder中使用whereRaw、selectRaw等方法結合原生表達式以提升安

優化Java應用程序中的內存使用率 優化Java應用程序中的內存使用率 Jul 28, 2025 am 02:40 AM

使用效率效率DatAstructuresLikeArrayLinkedLinkedLinkedListAndPrimitiveCollectionStoreCuceOverHead; 2.MinimizeObjectCreationByReosizobsobjects,usingsTringBuilderBuilderForforConcatenation,andCachingInation,andCachingingObjects; 3.PreventMemoryLeakSbySbyNullifyingReperences,lunterStatics interStatics interstatics

python三元操作員示例 python三元操作員示例 Jul 28, 2025 am 02:57 AM

Python的三元運算符用於簡潔地實現if-else判斷,其語法為“value_if_trueifconditionelsevalue_if_false”;1.可用於簡單賦值,如根據數值正負返回對應字符串;2.可避免除零錯誤,如判斷分母非零再進行除法;3.可在字符串格式化中根據條件選擇內容;4.可在列表推導式中為不同元素分配標籤;需注意該運算符僅適用於二分支情況,不宜多層嵌套,複雜邏輯應使用傳統if-elif-else結構以保證可讀性。

帶有項目反應堆和彈簧WebFlux的Java的反應性編程 帶有項目反應堆和彈簧WebFlux的Java的反應性編程 Jul 29, 2025 am 12:04 AM

響應式編程在Java中通過ProjectReactor和SpringWebFlux實現高並發、低延遲的非阻塞服務。 1.ProjectReactor提供Mono和Flux兩個核心類型,支持聲明式處理異步數據流,並通過操作符鏈進行轉換、過濾等操作;2.SpringWebFlux基於Reactor構建,支持註解式和函數式兩種編程模型,運行在Netty等非阻塞服務器上,可高效處理大量並發連接;3.使用WebFlux Reactor能提升I/O密集型場景下的並發能力與資源利用率,天然支持SSE、WebSo

CSS桌面固定示例 CSS桌面固定示例 Jul 29, 2025 am 04:28 AM

table-layout:fixed會強製表格列寬由第一行單元格寬度決定,避免內容影響佈局。 1.設置table-layout:fixed並指定表格寬度;2.為第一行th/td設置具體列寬比例;3.配合white-space:nowrap、overflow:hidden和text-overflow:ellipsis控製文本溢出;4.適用於後台管理、數據報表等需穩定佈局和高性能渲染的場景,能有效防止佈局抖動並提升渲染效率。

See all articles