메소드 구현은 매우 간단하며 두 가지 메소드를 제공합니다.
하나는 데이터 스트림으로 직렬화하는 것입니다. 전제는 모든 객체(객체에 포함된 객체...)가 Serialized 인터페이스를 상속해야 한다는 것입니다. 모두 상속되므로 매우 쉽습니다. 상속이 없고 모든 클래스를 수정할 계획이 없다면 두 번째 방법을 사용할 수 있습니다.
두 번째는 객체를 json으로 직렬화하고 json을 통해 복사하는 것입니다. 이 방법에는 net.sf.json.JSONObject를 사용해야 합니다.
구체적인 코드는 다음과 같습니다.
public class DeepCopy { /** * 深层拷贝 * * @param <T> * @param obj * @return * @throws Exception */ public static <T> T copy(T obj) throws Exception { //是否实现了序列化接口,即使该类实现了,他拥有的对象未必也有... 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()); } }
복사 메소드만 호출하면 됩니다.
자세한 JAVA 딥카피 DeepCopy 관련 글은 PHP 중국어 홈페이지를 주목해주세요!