成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

死磕Java面試:深拷貝與淺拷貝的實現原理

開發 前端
雖然大家都知道兩者表現形式不同點在哪里,但是很少去深究其底層原理,也不知道怎么才能優雅的實現一個深拷貝。其實工作中也常常需要實現深拷貝,今天一燈就帶大家一塊深入剖析一下深拷貝與淺拷貝的實現原理,并手把手教你怎么優雅的實現深拷貝。

深拷貝與淺拷貝的問題,也是面試中的常客。雖然大家都知道兩者表現形式不同點在哪里,但是很少去深究其底層原理,也不知道怎么才能優雅的實現一個深拷貝。其實工作中也常常需要實現深拷貝,今天一燈就帶大家一塊深入剖析一下深拷貝與淺拷貝的實現原理,并手把手教你怎么優雅的實現深拷貝。

1. 什么是深拷貝與淺拷貝

淺拷貝: 只拷貝棧內存中的數據,不拷貝堆內存中數據。

深拷貝: 既拷貝棧內存中的數據,又拷貝堆內存中的數據。

2. 淺拷貝的實現原理

由于淺拷貝只拷貝了棧內存中數據,棧內存中存儲的都是基本數據類型,堆內存中存儲了數組、引用數據類型等。

圖片

使用代碼驗證一下:

想要實現clone功能,需要實現 Cloneable 接口,并重寫 clone 方法。

  • 先創建一個用戶類
// 用戶的實體類,用作驗證
public class User implements Cloneable {
private String name;

// 每個用戶都有一個工作
private Job job;

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public Job getJob(){
return job;
}

public void setJob(Job job){
this.job = job;
}


@Override
public User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
return user;
}
}
  • 再創建一個工作類
// 工作的實體類,并沒有實現Cloneable接口
public class Job {
private String content;

public String getContent(){
return content;
}

public void setContent(String content){
this.content = content;
}
}
  • 測試淺拷貝
/**
* @author 一燈架構
* @apiNote Java淺拷貝示例
**/
public class Demo {

public static void main(String[] args) throws CloneNotSupportedException {
// 1. 創建用戶對象,{"name":"一燈架構","job":{"content":"開發"}}
User user1 = new User();
user1.setName("一燈架構");
Job job1 = new Job();
job1.setContent("開發");
user1.setJob(job1);

// 2. 拷貝用戶對象,name修改為"張三",工作內容修改"測試"
User user2 = user1.clone();
user2.setName("張三");
Job job2 = user2.getJob();
job2.setContent("測試");

// 3. 輸出結果
System.out.println("user原對象= " + user1);
System.out.println("user拷貝對象= " + user2);
}

}

輸出結果:

user原對象= {"name":"一燈架構","job":{"content":"測試"}}
user拷貝對象= {"name":"張三","job":{"content":"測試"}}

從結果中可以看出,對象拷貝把name修改為”張三“,原對象并沒有變,name是String類型,是基本數據類型,存儲在棧內存中。對象拷貝了一份新的棧內存數據,修改并不會影響原對象。

然后對象拷貝把Job中content修改為”測試“,原對象也跟著變了,原因是Job是引用類型,存儲在堆內存中。對象拷貝和原對象指向的同一個堆內存的地址,所以修改會影響到原對象。

3. 深拷貝的實現原理

深拷貝是既拷貝棧內存中的數據,又拷貝堆內存中的數據。

圖片

實現深拷貝有很多種方法,下面就詳細講解一下,看使用哪種方式更方便快捷。

3.1 實現Cloneable接口

通過實現Cloneable接口來實現深拷貝是最常見的。

想要實現clone功能,需要實現**Cloneable接口,并重寫clone**方法。

  • 先創建一個用戶類
// 用戶的實體類,用作驗證
public class User implements Cloneable {
private String name;

// 每個用戶都有一個工作
private Job job;

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public Job getJob(){
return job;
}

public void setJob(Job job){
this.job = job;
}


@Override
public User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
// User對象中所有引用類型屬性都要執行clone方法
user.setJob(user.getJob().clone());
return user;
}
}
  • 再創建一個工作類
// 工作的實體類,需要實現Cloneable接口
public class Job implements Cloneable {
private String content;

public String getContent(){
return content;
}

public void setContent(String content){
this.content = content;
}

@Override
protected Job clone() throws CloneNotSupportedException {
return (Job) super.clone();
}
}
  • 測試淺拷貝
/**
* @author 一燈架構
* @apiNote Java深拷貝示例
**/
public class Demo {

public static void main(String[] args) throws CloneNotSupportedException {
// 1. 創建用戶對象,{"name":"一燈架構","job":{"content":"開發"}}
User user1 = new User();
user1.setName("一燈架構");
Job job1 = new Job();
job1.setContent("開發");
user1.setJob(job1);

// 2. 拷貝用戶對象,name修改為"張三",工作內容修改"測試"
User user2 = user1.clone();
user2.setName("張三");
Job job2 = user2.getJob();
job2.setContent("測試");

// 3. 輸出結果
System.out.println("user原對象= " + user1);
System.out.println("user拷貝對象= " + user2);
}

}

輸出結果:

user原對象= {"name":"一燈架構","job":{"content":"開發"}}
user拷貝對象= {"name":"張三","job":{"content":"測試"}}

從結果中可以看出,user拷貝對象修改了name屬性和Job對象中內容,都沒有影響到原對象,實現了深拷貝。

通過實現Cloneable接口的方式來實現深拷貝,是Java中最常見的實現方式。

缺點是: 比較麻煩,需要所有實體類都實現Cloneable接口,并重寫clone方法。如果實體類中新增了一個引用對象類型的屬性,還需要添加到clone方法中。如果繼任者忘了修改clone方法,相當于挖了一個坑。

3.2 使用JSON字符串轉換

實現方式就是:

  • 先把user對象轉換成json字符串
  • 再把json字符串轉換成user對象

這是個偏方,但是偏方治大病,使用起來非常方便,一行代碼即可實現。

下面使用fastjson實現,使用Gson、Jackson也是一樣的:

import com.alibaba.fastjson.JSON;


/**
* @author 一燈架構
* @apiNote Java深拷貝示例
**/
public class Demo {

public static void main(String[] args) throws CloneNotSupportedException {
// 1. 創建用戶對象,{"name":"一燈架構","job":{"content":"開發"}}
User user1 = new User();
user1.setName("一燈架構");
Job job1 = new Job();
job1.setContent("開發");
user1.setJob(job1);

//// 2. 拷貝用戶對象,name修改為"張三",工作內容修改"測試"
User user2 = JSON.parseObject(JSON.toJSONString(user1), User.class);
user2.setName("張三");
Job job2 = user2.getJob();
job2.setContent("測試");

// 3. 輸出結果
System.out.println("user原對象= " + JSON.toJSONString(user1));
System.out.println("user拷貝對象= " + JSON.toJSONString(user2));
}

}

輸出結果:

user原對象= {"name":"一燈架構","job":{"content":"開發"}}
user拷貝對象= {"name":"張三","job":{"content":"測試"}}

從結果中可以看出,user拷貝對象修改了name屬性和Job對象中內容,并沒有影響到原對象,實現了深拷貝。

3.3 集合實現深拷貝

再說一下Java集合怎么實現深拷貝?

其實非常簡單,只需要初始化新對象的時候,把原對象傳入到新對象的構造方法中即可。

以最常用的ArrayList為例:

/**
* @author 一燈架構
* @apiNote Java深拷貝示例
**/
public class Demo {

public static void main(String[] args) throws CloneNotSupportedException {
// 1. 創建原對象
List<User> userList = new ArrayList<>();

// 2. 創建深拷貝對象
List<User> userCopyList = new ArrayList<>(userList);
}

}


責任編輯:武曉燕 來源: 一燈架構
相關推薦

2009-05-19 17:28:44

深拷貝淺拷貝clone()

2024-03-15 15:03:23

2022-07-26 08:07:03

Python淺拷貝深拷貝

2020-10-12 08:35:22

JavaScript

2023-05-17 08:42:46

深拷貝Golang

2021-01-08 06:15:09

深拷貝淺拷貝寫時拷貝

2017-08-16 13:30:05

Java深拷貝淺拷貝

2021-09-10 07:41:06

Python拷貝Python基礎

2021-07-16 12:33:24

Javascript深拷貝淺拷貝

2024-04-17 09:01:08

Python深拷貝淺拷貝

2018-09-26 14:37:17

JavaScript前端編程語言

2020-06-23 08:41:47

JavaScript開發技術

2019-02-25 08:58:16

Python深拷貝淺拷貝

2024-02-05 22:56:16

C++拷貝開發

2021-09-27 11:07:11

深拷貝淺拷貝內存

2025-04-27 09:45:58

JavaScript深拷貝淺拷貝

2020-08-03 08:24:26

原型模式拷貝

2023-09-22 12:21:33

Python深拷貝淺拷貝

2018-05-10 14:20:18

前端JavaScript深拷貝

2022-09-30 15:03:09

C語言深拷貝淺拷貝
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区不卡 | 日韩欧美网 | 97色在线视频 | 国产精品18hdxxxⅹ在线 | 国产精品免费一区二区三区四区 | 成年人在线观看 | 日韩在线小视频 | 国产一区久久久 | 911精品美国片911久久久 | 久久久久久久久国产精品 | 亚洲电影一区二区三区 | 在线看片网站 | 国产日韩欧美一区 | 国产午夜精品视频 | 欧美激情精品久久久久久 | 羞羞视频网站免费观看 | 激情麻豆视频 | 亚洲精品9999久久久久 | 不卡一区二区三区四区 | 免费一级片 | 黑人性hd | 波多野结衣一区二区三区 | 精品国产91 | 自拍中文字幕 | 久久国产精品-国产精品 | 午夜av成人 | 色婷婷av久久久久久久 | 99久久中文字幕三级久久日本 | 亚洲成网| 97精品久久 | 国产精品久久久久久婷婷天堂 | 亚洲香蕉在线视频 | 日韩在线一区二区三区 | 91精品国产91久久综合桃花 | 日韩在线视频免费观看 | 国产一区二区电影网 | 精品视频一区二区三区 | 欧美中文字幕一区 | 久久精品欧美一区二区三区不卡 | 欧美午夜精品久久久久久浪潮 | 国内自拍第一页 |