JAVA 深層拷貝 DeepCopy的使用詳解
方法實(shí)現(xiàn)很簡單,提供兩種方式:
一種是序列化成數(shù)據(jù)流,前提是所有對象(對象中包含的對象...)都需要繼承Serializable接口,如果都繼承了那很容易,如果沒有繼承,而且也不打算修改所有類,可以用第二種方式。
第二種是將對象序列化為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)了,他擁有的對象未必也有...
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("對象中包含沒有繼承序列化的對象");
} 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)文章
Linux 下通過 java 命令啟動(dòng) jar 包常見方式小結(jié)
這篇文章主要介紹了Linux 下通過 java 命令啟動(dòng) jar 包常見方式小結(jié),后臺啟動(dòng)jar包命令大致有五種,每種方式結(jié)合代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2023-12-12Java向上轉(zhuǎn)型和向下轉(zhuǎn)型的區(qū)別說明
這篇文章主要介紹了Java向上轉(zhuǎn)型和向下轉(zhuǎn)型的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06java finally塊執(zhí)行時(shí)機(jī)全面分析
下面小編就為大家?guī)硪黄猨ava finally塊執(zhí)行時(shí)機(jī)全面分析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08SpringCloud入門實(shí)驗(yàn)環(huán)境搭建
這篇文章主要介紹了SpringCloud入門實(shí)驗(yàn)環(huán)境搭建的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用SpringCloud,感興趣的朋友可以了解下2021-04-04Spark學(xué)習(xí)筆記Spark Streaming的使用
這篇文章主要介紹了Spark學(xué)習(xí)筆記Spark Streaming的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06