更新時間:2022-09-08 10:33:49 來源:動力節點 瀏覽777次
在 Java 中,我們如何復制一個對象呢?我們都知道Java Object類中的clone方法,該方法用于克隆對象。
假設我們有一個名為Student的實體,它擁有另一個名為Result的實體。
結果 POJO
公共 最終 類 結果{
私有 最終 int 標記;
公共 結果(最終 整數 標記){
這個。標記 = 標記;
}
公共 int getMarks () {
返回 這個。標記;
}
@覆蓋
公共 字符串 toString () {
返回 更多對象。toStringHelper ( this.getClass ( )) 。添加(“標記”,這個。標記)。toString ();
}
}
學生 POJO
公共 期末 班 學生{
私有 最終 字符串 名稱;
私人 最終 結果 結果;
公共 學生(最終 字符串 名稱,最終 結果 結果){
checkNotNull (名稱);
checkNotNull (結果);
這個。名稱 = 名稱;
這個。結果 = 結果;
}
公共 字符串 getName () {
返回 這個。名稱;
}
公共 結果 getResult () {
返回 這個。結果;
}
@覆蓋
公共 字符串 toString () {
返回 更多對象。toStringHelper ( this.getClass ( )) 。添加(“名稱”,這個。名稱)。添加(“結果”,這個。結果)。toString ();
}
}
因此, Student的每個對象都將持有一個指向實際Result對象的指針。
應用程序客戶端
公共 最終 類 DefalutCopyConstructor {
公共 靜態 無效 主要(最終 字符串[]參數){
最終 結果 結果 = 新 結果(50);
final Student student = new Student ( "Sam" , result );
系統。出來。println (學生);
}
}
如果您運行前面的代碼,您可以獲得一個Student對象,該對象包含對Result對象的引用?,F在,如果想創建另一個對象,可以像在前面的示例中那樣創建它。
公共 最終 類 DefalutCopyConstructor {
公共 靜態 無效 主要(最終 字符串[]參數){
最終 結果 result1 = 新 結果( 50 );
final Student student1 = new Student ( "Sam" , result1 );
最終 結果 result2 = 新 結果( 50 );
final Student student2 = new Student ( "Dean" , result2 );
系統。出來。打?。▽W生1);
系統。出來。打?。▽W生2);
}
}
現在,我們創建了另一個學生對象。如果您使用相等運算符進行檢查,它將報告錯誤,因為兩個引用(student1 和 student2)都指向堆中的不同對象。
如果我們想將 student1 的對象復制到 student2 的引用中,會嘗試編寫如下語法。
公共 最終 類 DefalutCopyConstructor {
公共 靜態 無效 主要(最終 字符串[]參數){
最終 結果 result1 = 新 結果( 50 );
final Student student1 = new Student ( "Sam" , result1 );
最終 學生 student2 = 新 學生( student1 );
系統。出來。打?。▽W生1);
系統。出來。打?。▽W生2);
}
}
這顯然會報編譯錯誤。
構造 函數Student ( Student )未定義_
但是想想,Java 可以給我們一個像這樣的默認復制構造函數,但它沒有。
為什么?因為淺拷貝的危險
在這里,student1 指的是一個包含Result對象引用的Student對象?,F在,student2 將引用一個全新的Student對象,但這個新的Student對象仍將包含對舊Result對象的Result引用。因此,您可以清楚地看到對象不是深度復制而是引用。
由于復制對象的風險,Java 沒有提供默認復制構造函數。
然后我們可以嘗試實現我們自己的復制構造函數來深度復制對象。讓我們嘗試實現它。
帶有復制構造函數的結果 POJO
公共 最終 類 結果{
私有 最終 int 標記;
公共 結果(最終 整數 標記){
這個。標記 = 標記;
}
公共 結果(最終 結果 結果){
這個。標記 = 結果。獲取標記();
}
公共 int getMarks () {
返回 這個。標記;
}
@覆蓋
公共 字符串 toString () {
返回 更多對象。toStringHelper ( this.getClass ( )) 。添加(“標記”,這個。標記)。toString ();
}
}
帶有復制構造函數的學生 POJO
公共 期末 班 學生{
私有 最終 字符串 名稱;
私人 最終 結果 結果;
公共 學生(最終 字符串 名稱,最終 結果 結果){
checkNotNull (名稱);
checkNotNull (結果);
這個。名稱 = 名稱;
這個。結果 = 結果;
}
公共 學生(最終 學生 學生){
這個。姓名 = 學生。獲取名稱();
這個。結果 = 新 結果(學生。getResult ());
}
公共 字符串 getName () {
返回 這個。名稱;
}
公共 結果 getResult () {
返回 這個。結果;
}
@覆蓋
公共 字符串 toString () {
返回 更多對象。toStringHelper ( this.getClass ( )) 。添加(“名稱”,這個。名稱)。添加(“結果”,這個。結果)。toString ();
}
}
客戶端應用程序
公共 最終 類 DefalutCopyConstructor {
公共 靜態 無效 主要(最終 字符串[]參數){
最終 結果 result1 = 新 結果( 50 );
final Student student1 = new Student ( "Sam" , result1 );
最終 學生 student2 = 新 學生( student1 );
系統。出來。打印(學生1);
系統。出來。打印(學生2);
}
}
由于這個實現,我們完全擺脫了淺拷貝問題。這意味著現在,我們可以精確復制每個對象,無論是Student對象還是Result對象。Student對象的副本將不再引用任何其他Student對象包含的Result對象。相反,它將包含一個新的Result對象引用。
以上就是關于“默認拷貝構造函數示例”介紹,大家如果想了解更多相關知識,可以關注一下動力節點的Java基礎教程技術文檔,里面還有更豐富的知識等著大家去學習,希望對大家能夠有所幫助。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習