Java中深拷貝和淺拷貝的區(qū)別解析
引用拷貝和對象拷貝
(1)引用拷貝:將對象的引用賦值給引用類型的變量
Object obj = new Object(); Object obj1 = obj;
(2)對象拷貝 創(chuàng)建對象的一個副本,其中副本和源對象的引用是兩個不同的地址,而不是把一個引用賦值給一個新的引用類型的變量
class Demo{
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User();
User user1 = (User)user.clone();
System.out.println(user);
System.out.println(user1);
}
}
class User implements Cloneable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}淺拷貝和深拷貝都是對象拷貝
- 淺拷貝:源對象和拷貝對象的存放地址不同,但被復(fù)制的源對象的引用類型屬性存放的地址仍然和源對象的引用類型屬性相同,修改引用類型屬性的屬性會影響相互影響。
- 深拷貝:源對象和拷貝對象的存放地址不同,源對象和拷貝對象各自的引用類型存放的地址也和源對象的引用類型屬性不同,修改引用類型屬性的屬性不會相互影響拷貝對象和源對象。
常見的淺拷貝方式
(1)一個引用類型變量直接賦值給另一個變量
(2)BeaUtil.copyProperties()
常見的深拷貝方式
(1)通過構(gòu)造器或new的方式
(2)重寫繼承至Object方法的clone方法,并實現(xiàn)Cloneable接口 如果在沒有實現(xiàn)Cloneable 接口的實例上調(diào)用 Object 的 clone 方法,則會導(dǎo)致拋出 CloneNotSupportedException 異常,實現(xiàn)Cloneable 接口的目的是:為了告知JVM,此對象允許拷貝
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User(1, "測試");
User user1 = user.clone();
System.out.println(user1);
}
}
class User implements Cloneable{
private Integer id;
private String name;
//必須重寫此方法
@Override
protected User clone() throws CloneNotSupportedException {
return (User)super.clone();
}
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
}注意: 當(dāng)通過Cloneable接口實現(xiàn)深拷貝時,拷貝的源對象的屬性如果是引用對象(String類型除外),則該屬性也需要實現(xiàn)Cloneable接口,并覆寫clone方法,否則該屬性是進行的淺拷貝。
深拷貝特殊情況(String類型)
String類型屬性:Clonable拷貝后兩個對象的相同屬性指向了通過字符串,但字符串是不可以修改的,存放在常量池中,當(dāng)其中1個對象的該屬性指向另個字符串時,另外一個對象的屬性的引用仍指向原字符串。
public class ProtoTypeDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
person.setId(1L);
person.setName("test");
User user = new User();
user.setUsername("測試");
person.setUser(user);
Person person1 = person.clone();
User user1 = user.clone();
user1.setUsername("cs");
person1.setUser(user1);
System.out.println(person1);//Person{id=1, name='test', user=User{username='cs'}}
System.out.println(person);//Person{id=1, name='test', user=User{username='測試'}}
}
}
public class Person implements Cloneable {
private Long id;
private String name;
private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", user=" + user +
'}';
}
}
public class User implements Cloneable{
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
'}';
}
}(3)序列化的方式:FastJson、Gson等都可以
class Main{
public static void main(String[] args) {
User user = new User(1, "測試");
//序列化
String s = JSONObject.toJSONString(user);
//反序列化
System.out.println(s);
User user1 = JSON.parseObject(s, User.class);
System.out.println(user1);
}
}
public class User {
private Integer id;
private String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}到此這篇關(guān)于Java中深拷貝和淺拷貝的區(qū)別解析的文章就介紹到這了,更多相關(guān)Java深拷貝和淺拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用Spire.Doc實現(xiàn)XML轉(zhuǎn)PDF的實戰(zhàn)指南
本文介紹了使用Spire.DocforJava將XML轉(zhuǎn)換為PDF的過程,首先說明了XML和PDF的應(yīng)用場景,然后通過Maven引入依賴,核心代碼展示了加載XML并轉(zhuǎn)換為PDF的方法,最后討論了進階設(shè)置、注意事項及常見問題,幫助開發(fā)者更好地完成轉(zhuǎn)換任務(wù),需要的朋友可以參考下2026-04-04
springboot中在非bean類中調(diào)用bean的實現(xiàn)方法
在Spring Boot中,非Bean類調(diào)用Bean方法通常需要通過靜態(tài)方法獲取Bean實例,然后調(diào)用相應(yīng)的方法,這種方法避免了直接在非Bean類中注入Bean,保持了代碼的簡潔和可維護性,通過這種方式,可以在不改變原有代碼結(jié)構(gòu)的情況下,實現(xiàn)Bean方法的調(diào)用2025-02-02
POI XSSFSheet shiftRows bug問題解決
這篇文章主要介紹了POI XSSFSheet shiftRows bug問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
Java中l(wèi)ist.contains()的用法及拓展
List集合相信大家在開發(fā)過程中幾乎都會用到,有時候難免會遇到集合里的數(shù)據(jù)是重復(fù)的,需要進行去除,下面這篇文章主要給大家介紹了關(guān)于Java中l(wèi)ist.contains()的用法及拓展的相關(guān)資料,需要的朋友可以參考下2023-03-03
Java CRM系統(tǒng)用戶登錄功能實現(xiàn)代碼實例
這篇文章主要介紹了Java CRM系統(tǒng)用戶登錄功能實現(xiàn)代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04

