JAVA 深層拷貝 DeepCopy的使用詳解
方法實(shí)現(xiàn)很簡(jiǎn)單,提供兩種方式:
一種是序列化成數(shù)據(jù)流,前提是所有對(duì)象(對(duì)象中包含的對(duì)象...)都需要繼承Serializable接口,如果都繼承了那很容易,如果沒有繼承,而且也不打算修改所有類,可以用第二種方式。
第二種是將對(duì)象序列化為json,通過json來實(shí)現(xiàn)拷貝,這種方式需要用到net.sf.json.JSONObject。
具體代碼如下:
public class DeepCopy {
/**
* 深層拷貝
*
* @param <T>
* @param obj
* @return
* @throws Exception
*/
public static <T> T copy(T obj) throws Exception {
//是否實(shí)現(xiàn)了序列化接口,即使該類實(shí)現(xiàn)了,他擁有的對(duì)象未必也有...
if(Serializable.class.isAssignableFrom(obj.getClass())){
//如果子類沒有繼承該接口,這一步會(huì)報(bào)錯(cuò)
try {
return copyImplSerializable(obj);
} catch (Exception e) {
//這里不處理,會(huì)運(yùn)行到下面的嘗試json
}
}
//如果序列化失敗,嘗試json序列化方式
if(hasJson()){
try {
return copyByJson(obj);
} catch (Exception e) {
//這里不處理,下面返回null
}
}
return null;
}
/**
* 深層拷貝 - 需要類繼承序列化接口
* @param <T>
* @param obj
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static <T> T copyImplSerializable(T obj) throws Exception {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
Object o = null;
//如果子類沒有繼承該接口,這一步會(huì)報(bào)錯(cuò)
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
bais = new ByteArrayInputStream(baos.toByteArray());
ois = new ObjectInputStream(bais);
o = ois.readObject();
return (T) o;
} catch (Exception e) {
throw new Exception("對(duì)象中包含沒有繼承序列化的對(duì)象");
} finally{
try {
baos.close();
oos.close();
bais.close();
ois.close();
} catch (Exception e2) {
//這里報(bào)錯(cuò)不需要處理
}
}
}
/**
* 是否可以使用json
* @return
*/
private static boolean hasJson(){
try {
Class.forName("net.sf.json.JSONObject");
return true;
} catch (Exception e) {
return false;
}
}
/**
* 深層拷貝 - 需要net.sf.json.JSONObject
* @param <T>
* @param obj
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static <T> T copyByJson(T obj) throws Exception {
return (T)JSONObject.toBean(JSONObject.fromObject(obj),obj.getClass());
}
}
只需要調(diào)用copy方法就行。
相關(guān)文章
Java 14 發(fā)布了,你還會(huì)使用Lombok?
2020年3月17日發(fā)布,Java正式發(fā)布了JDK 14 ,目前已經(jīng)可以開放下載。在JDK 14中,共有16個(gè)新特性,本文主要來介紹其中的一個(gè)特性:JEP 359: Records,需要的朋友可以參考下2020-04-04
Java中LocalDate日期格式轉(zhuǎn)換(使用系統(tǒng)時(shí)區(qū))
本文主要介紹了Java中LocalDate日期格式轉(zhuǎn)換(使用系統(tǒng)時(shí)區(qū)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2007-02-02
@MapperScan掃描包里混有@Service等問題如何解決
這篇文章主要介紹了@MapperScan掃描包里混有@Service等問題如何解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
logback StatusListener的定義方法源碼解讀
這篇文章主要為大家介紹了logback StatusListener的定義方法源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
學(xué)會(huì)IDEA REST Client后就可以丟掉postman了
這篇文章主要介紹了學(xué)會(huì)IDEA REST Client后就可以丟掉postman了,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
play for scala 實(shí)現(xiàn)SessionFilter 過濾未登錄用戶跳轉(zhuǎn)到登錄頁面
這篇文章主要介紹了play for scala 實(shí)現(xiàn)SessionFilter 過濾未登錄用戶跳轉(zhuǎn)到登錄頁面的相關(guān)資料,需要的朋友可以參考下2016-11-11
Java編程實(shí)現(xiàn)判斷網(wǎng)上鄰居文件是否存在的方法
這篇文章主要介紹了Java編程實(shí)現(xiàn)判斷網(wǎng)上鄰居文件是否存在的方法,涉及Java針對(duì)路徑轉(zhuǎn)換及字符串操作的相關(guān)技巧,需要的朋友可以參考下2015-10-10
IDEA2020.2.3 "reading maven projects"卡住的問題
這篇文章主要介紹了IDEA2020.2.3 "reading maven projects"卡住的問題及問題原因探究,通過多種方法給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-10-10
SpringBoot 啟動(dòng)方法run()源碼解析
這篇文章主要介紹了SpringBoot 啟動(dòng)方法run()源碼賞析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03

