JAVA 深層拷貝 DeepCopy的使用詳解
更新時間:2013年07月19日 11:46:50 作者:
最近需要用到比較兩個對象屬性的變化,其中一個是oldObj,另外一個是newObj,oldObj是newObj的前一個狀態(tài),所以需要在newObj的某個狀態(tài)時,復制一個一樣的對象,由于JAVA不支持深層拷貝,因此專門寫了一個方法
方法實現(xiàn)很簡單,提供兩種方式:
一種是序列化成數(shù)據(jù)流,前提是所有對象(對象中包含的對象...)都需要繼承Serializable接口,如果都繼承了那很容易,如果沒有繼承,而且也不打算修改所有類,可以用第二種方式。
第二種是將對象序列化為json,通過json來實現(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 {
//是否實現(xiàn)了序列化接口,即使該類實現(xiàn)了,他擁有的對象未必也有...
if(Serializable.class.isAssignableFrom(obj.getClass())){
//如果子類沒有繼承該接口,這一步會報錯
try {
return copyImplSerializable(obj);
} catch (Exception e) {
//這里不處理,會運行到下面的嘗試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;
//如果子類沒有繼承該接口,這一步會報錯
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) {
//這里報錯不需要處理
}
}
}
/**
* 是否可以使用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 命令啟動 jar 包常見方式小結(jié)
這篇文章主要介紹了Linux 下通過 java 命令啟動 jar 包常見方式小結(jié),后臺啟動jar包命令大致有五種,每種方式結(jié)合代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧2023-12-12Java向上轉(zhuǎn)型和向下轉(zhuǎn)型的區(qū)別說明
這篇文章主要介紹了Java向上轉(zhuǎn)型和向下轉(zhuǎn)型的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06