首先需要明白,淺拷貝和深拷貝都是針對一個已有對象的操作。那先來看看淺拷貝和深拷貝的概念:
對象拷貝有哪些
· 對象拷貝(Object Copy)就是將一個對象的屬性拷貝到另一個有著相同類類型的對象中去。在程序中拷貝對象是很常見的,主要是為了在新的上下文環境中復用對象的部分或全部數據。
· Java中有三種類型的對象拷貝:淺拷貝(Shallow Copy)、深拷貝(Deep Copy)、延遲拷貝(Lazy Copy)。
理解淺拷貝
淺拷貝是按位拷貝對象,它會創建一個新對象,這個對象有著原始對象屬性值的一份精確拷貝。如果屬性是基本類型,拷貝的就是基本類型的值;如果屬性是內存地址(引用類型),拷貝的就是內存地址 ,因此如果其中一個對象改變了這個地址,就會影響到另一個對象。
理解深拷貝
深拷貝會拷貝所有的屬性,并拷貝屬性指向的動態分配的內存。當對象和它所引用的對象一起拷貝時即發生深拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。
序列化進行拷貝
可能你會問,序列化是屬于那種類型拷貝?答案是:通過序列化來實現深拷貝。可以思考一下,為何序列化對象要用深拷貝而不是用淺拷貝呢?
可以序列化是干什么的?它將整個對象圖寫入到一個持久化存儲文件中并且當需要的時候把它讀取回來, 這意味著當你需要把它讀取回來時你需要整個對象圖的一個拷貝。這就是當你深拷貝一個對象時真正需要的東西。請注意,當你通過序列化進行深拷貝時,必須確保對象圖中所有類都是可序列化的。
延遲拷貝
延遲拷貝是淺拷貝和深拷貝的一個組合,實際上很少會使用。
當最開始拷貝一個對象時,會使用速度較快的淺拷貝,還會使用一個計數器來記錄有多少對象共享這個數據。當程序想要修改原始的對象時,它會決定數據是否被共享(通過檢查計數器)并根據需要進行深拷貝。
延遲拷貝從外面看起來就是深拷貝,但是只要有可能它就會利用淺拷貝的速度。當原始對象中的引用不經常改變的時候可以使用延遲拷貝。由于存在計數器,效率下降很高,但只是常量級的開銷。而且, 在某些情況下, 循環引用會導致一些問題。
如何選擇拷貝方式?
· 如果對象的屬性全是基本類型的,那么可以使用淺拷貝。
· 如果對象有引用屬性,那就要基于具體的需求來選擇淺拷貝還是深拷貝。
· 意思是如果對象引用任何時候都不會被改變,那么沒必要使用深拷貝,只需要使用淺拷貝就行了。如果對象引用經常改變,那么就要使用深拷貝。沒有一成不變的規則,一切都取決于具體需求。
更多關于“Java培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓經驗,課程大綱更科學更專業,有針對零基礎的就業班,有針對想提升技術的好程序員班,高品質課程助理你實現java程序員夢想。