java 克隆
浅拷贝和深拷贝的区别:
浅拷贝(Shallow Clone):被复制对象的所有变量都含有与原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。
深拷贝(Deep Clone):被复制对象的所有变量都含有与原来对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制的新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把复制的对象所引用的对象都复制了一遍。
方法一:实现 Cloneable 接口并重写 Object 类中的 clone() 方法
import lombok.Data; public class Test { @Data static class Hello implements Cloneable { private String name; public Hello(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public static void main(String[] args) throws CloneNotSupportedException { Hello hello = new Hello("name"); Hello clone = (Hello) hello.clone(); System.out.println(clone); } }
方法二:使用spring的BeanUtils(推荐)
import lombok.Data; import org.springframework.beans.BeanUtils; public class Test { @Data static class Hello { private String name; public Hello() { } public Hello(String name) { this.name = name; } } public static void main(String[] args) { Hello source = new Hello("name"); Hello target = new Hello(); BeanUtils.copyProperties(source, target); System.out.println(target); } }
方法三:使用fastjson通过对象json序列化和反序列化来完成对象复制(深度克隆)
import com.alibaba.fastjson.JSON; import lombok.Data; public class Test { @Data static class Hello { private String name; public Hello() { } public Hello(String name) { this.name = name; } } public static void main(String[] args) { Hello source = new Hello("name"); String sourceStr = JSON.toJSONString(source);//序列化为json Hello target = JSON.parseObject(sourceStr, Hello.class);//反序列化 System.out.println(target); } }
方法四:利用序列化实现对象的拷贝(深度克隆)
/** * 对象深拷贝 * * @param obj * @param <T> * @return */ public static <T extends Serializable> T deepClone2(T obj) { T cloneObj = null; try { //写入字节流 ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream obs = new ObjectOutputStream(out); obs.writeObject(obj); obs.close(); //分配内存,写入原始对象,生成新对象 ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(ios); //返回生成的新对象 cloneObj = (T) ois.readObject(); ois.close(); } catch (Exception e) { e.printStackTrace(); } finally { //关闭流 } return cloneObj; } /** * 对象深拷贝 try-with-resources写法 * * @param obj * @param <T> * @return */ public static <T extends Serializable> T deepClone(T obj) { T cloneObj = null; try (ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream obs = new ObjectOutputStream(out); ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(ios); ) { obs.writeObject(obj); cloneObj = (T) ois.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return cloneObj; } /** * List深拷贝 * * @param src * @param <T> * @return */ public static <T> List<T> deepCloneList2(List<T> src) { List<T> dest = null; try { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(byteIn); dest = (List<T>) in.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { //关闭流 } return dest; } /** * List深拷贝 try-with-resources写法 * * @param src * @param <T> * @return */ public static <T> List<T> deepCloneList(List<T> src) { List<T> dest = null; try { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(byteIn); dest = (List<T>) in.readObject(); } catch (Exception e) { e.printStackTrace(); }return dest; }
更多资料: Java程序员面试笔试宝典 第2版 1.3 Java中clone方法的作用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2018-03-27 java == 与 equals