A. 深拷貝和淺拷貝的區別
1、淺拷貝可以使用列表自帶的()函數(如list.()),或者使用模塊的()函數。深拷貝只能使用模塊的deep(),所以使用前要導入:from import deep。
2、 如果拷貝的對象里的元素只有值,沒有引用,那淺拷貝和深拷貝沒有差別,都會將原有對象復制一份,產生一個新對象,對新對象里的值進行修改不會影響原有對象,新對象和原對象完全分離開。
3、 如果拷貝的對象里的元素包含引用(像一個列表裡儲存著另一個列表,存的就是另一個列表的引用),那淺拷貝和深拷貝是不同的,淺拷貝雖然將原有對象復制一份。
但是依然保存的是引用,所以對新對象里的引用里的值進行修改,依然會改變原對象里的列表的值,新對象和原對象完全分離開並沒有完全分離開。而深拷貝則不同,它會將原對象里的引用也新創建一個,即新建一個列表,然後放的是新列表的引用,這樣就可以將新對象和原對象完全分離開。
B. 淺復制和深復制的區別 java
淺復制和深復制的區別 java
大體上來說,深拷貝與淺拷貝的區別主要還是在於指針(或與指針)方面,淺拷貝只是簡單的把源對象(這個是指廣義的對象,不僅僅單指類的實例)的指針賦值給目標對象,對目標指針的操作就是對源對象的操作,所以在很多情況下,目標對象析構(或跳出其可見域)之後,源對象相關部分也就一同析構了。而深拷貝,是為目標對象重新分配空間,這樣可以與源對象的操作分開。
C. java如何實現對象的深克隆
/**定義用戶**/
publicclassUser{
privateStringname;
privateAddressaddress;
//constructors,gettersandsetters
}
/**地址**/
publicclassAddress{
privateStringcity;
privateStringcountry;
//constructors,gettersandsetters
}
重載clone()方法
Object父類有個clone()的拷貝方法,不過它是protected類型的,
我們需要重寫它並修改為public類型。
除此之外,子類還需要實現Cloneable介面來告訴JVM這個類是可以拷貝的。
重寫代碼
讓我們修改一下User類,Address類,實現Cloneable介面,使其支持深拷貝。
/**
*地址
*/
{
privateStringcity;
privateStringcountry;
//constructors,gettersandsetters
@Override
publicAddressclone(){
return(Address)super.clone();
}
}
/**
*用戶
*/
{
privateStringname;
privateAddressaddress;
//constructors,gettersandsetters
@Override
publicUserclone(){
Useruser=(User)super.clone();
user.setAddress(this.address.clone());
returnuser;
}
}
需要春轎注意的是,super.clone()其實是淺拷貝,
所以在重寫User類的clone()方法時,address對象需要調用address.clone()重新賦值。
擴展:
為什麼要克隆?
大家先思考一個問題,為什麼需要克隆對象?直接new一個對象不行嗎?
答案是:克隆的對象可能包含一些已經修改過的屬性,而new出來的對象的屬性都還是初始化時候的值,所以當需要一個新的對象來保存當前對象的「狀態」就靠clone方法了。那麼我把這個對象的臨時屬性一個一個的賦值給我新new的對象不也行嘛?可以是可以,但前老是一來麻煩不說,二來,大家通過上面的源碼都發現了clone是一個native方法,就是快啊,在底層實現的。
提個醒,我們常見的Objecta=newObject();Objectb;b=a;這種形式的代碼復制的是引用,即對扒悔肆象在內存中的地址,a和b對象仍然指向了同一個對象。
而通過clone方法賦值的對象跟原來的對象時同時獨立存在的。
D. 什麼是深拷貝和淺拷貝
淺拷貝就是指對象復制的時候只復制一層;深拷貝是指復制對象的所有層級。
深拷貝和淺拷貝,主要是對象發生復制的時候,根據復制的層級不同來區分的。很多人在這里經常變數賦值發生混淆。對於JavaScript數組等復雜的數據類型來說,將其賦值給其它變數,其實只是復制了對象的地址給它,兩個變數指向的是同一個對象,因此普通的賦值既不是深拷貝也不是淺拷貝。
深拷貝和淺拷仔芹貝需要注意的地方就是可變元素的拷貝:
在淺拷貝時,拷貝出來的新對象的地址和原對象是不一樣的,但是新對象裡面的可變元素(如列表)的地址和原對滲戚做象里的可變元素的地址是相同的,也就是說淺拷貝它拷貝的是淺層次的數據結構(不可變元素),對象里的可變元素作為深層次的數據結構並沒有被拷貝到新地址裡面去。
而是和原對象里的可變元素指向同一個地址,所以在新對象或原對象里對這個可變元素做修改時,兩個對象叢衡是同時改變的,但是深拷貝不會這樣,這個是淺拷貝相對於深拷貝最根本的區別。
E. java 中對象賦值 是淺拷貝還是深層拷貝
對於對象賦值,引用類型是淺拷貝,復制的是引用(即地址),基本類型是深層拷貝(直接復制值)。
F. JAVA 中淺拷貝與深拷貝有什麼區別
淺拷貝 指的是你的類本身被拷貝,而沒有拷貝類本身屬性中的類
深拷貝 指的是包含類本身和屬性類在內的所有類的拷貝。
簡單點說:
就是淺拷貝的兩個對象中的屬性還會指向同一個類,而深拷貝則全部單獨了。也就是說深拷貝把關聯關系也拷貝了。
具體例子你可以參看我的blog,裡面篇文章介紹:)
G. java深拷貝和淺拷貝的區別
淺拷貝:只復制一個對象,對象內部存在的指向其他對象數組或者引用則不復制
深拷貝:對象,對象內部的引用均復制
示例:
publicstaticObject(ObjectoldObj){
Objectobj=null;
try{
//Writetheobjectouttoabytearray
ByteArrayOutputStreambos=newByteArrayOutputStream();
ObjectOutputStreamout=newObjectOutputStream(bos);
out.writeObject(oldObj);
out.flush();
out.close();
//
//aoftheobjectbackin.
ByteArrayInputStreambis=newByteArrayInputStream(bos.toByteArray());
ObjectInputStreamin=newObjectInputStream(bis);
obj=in.readObject();
}catch(IOExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptioncnfe){
cnfe.printStackTrace();
}
returnobj;
}
H. 淺拷貝與深拷貝的區別是什麼
簡單的來說就是,在有指針的情況下,淺拷貝只是增加了一個指針指向已經存在的內存,而深拷貝就是增加一個指針並且申請一個新的內存,使這個增加的指針指向這個新雀灶的內存頃模扮,採用深拷貝的情況下,釋放內存的時候就不會出現在淺拷貝時重復釋放同一內存的錯誤!
我列舉一個例子來說吧:
你正在編寫C++程序中有時用到,操作符的重載。最能體現深層拷貝與淺層拷貝的,就是『=』的重載。
看下面一個簡單的程序:
class string
{
char *m_str;
public:
string(char *s)
{
m_str=s;
}
string()
{};
String & operator=(const string s)
{
m_str=s.m_str;
return *this
}
};
int main()
{
string s1("abc"),s2;
s2=s1;
cout<
}
上面的 =重載其是就是實現了淺拷貝原因。是由碼拆於對象之中含有指針數據類型.s1,s2恰好指向同一各內存。所以是淺拷貝。而你如果修改一下原來的程序:
string&operator=(const string&s)
{
if(strlen(m_str)!=strlen(s.m_str))
m_str=new char[strlen(s.m_str)+1];
if(*this!=s)
str(m_str,s.m_str);
return *this;
}
這樣你就實現了深拷貝,原因是你為被賦值對象申請了一個新的內存所以就是深拷貝。
I. java深拷貝和淺拷貝的區別
深拷拿尺貝和淺拷貝最大的區別在於淺拷貝更多時候拷貝的是地址消告高、引用這種東西,而深拷貝則是拷友舉貝了一個新地址的對象,具體可以參考以下網址
網頁鏈接