| |
| public interface Cloneable { |
| } |
没有引用类型字段时
| class Writer implements Cloneable { |
| private int age; |
| private String name; |
| |
| |
| |
| @Override |
| public String toString() { |
| return "Writer{" + |
| "age=" + age + |
| ", name='" + name + '\'' + |
| '}'; |
| } |
| |
| @Override |
| protected Object clone() throws CloneNotSupportedException { |
| return super.clone(); |
| } |
| } |
- 如果一个类没有实现 Cloneable 接口,即便它重写了
clone()
方法,依然是无法调用该方法进行对象克隆的,程序在执行 clone()
方法的时候会抛出 CloneNotSupportedException 异常
| public static void main(String[] args) throws CloneNotSupportedException { |
| Writer writer1 = new Writer(18, "二狗"); |
| Writer writer2 = (Writer) writer1.clone(); |
| |
| System.out.println("浅拷贝后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| writer2.setName("铁蛋"); |
| |
| System.out.println("调整了 writer2 的 name 后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
- 字符串 String 是不可变对象,一个新的值必须在字符串常量池中开辟一段新的内存空间,所以并没有影响到字符串二狗的值
有引用类型字段时
浅拷贝
| class Book { |
| private String bookName; |
| private int price; |
| |
| |
| |
| @Override |
| public String toString() { |
| return super.toString().substring(26) + |
| " bookName='" + bookName + '\'' + |
| ", price=" + price + |
| '}'; |
| } |
| } |
| |
| class Writer implements Cloneable { |
| private int age; |
| private String name; |
| |
| private Book book; |
| |
| |
| |
| @Override |
| public String toString() { |
| return "Writer{" + |
| "age=" + age + |
| ", name='" + name + '\'' + |
| ", book=" + book + |
| '}'; |
| } |
| |
| @Override |
| protected Object clone() throws CloneNotSupportedException { |
| return super.clone(); |
| } |
| } |
| public static void main(String[] args) throws CloneNotSupportedException { |
| Writer writer1 = new Writer(18,"二狗",new Book("编译原理",100)); |
| Writer writer2 = (Writer) writer1.clone(); |
| |
| System.out.println("浅拷贝后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| Book book = writer2.getBook(); |
| book.setBookName("离散数学"); |
| book.setPrice(70); |
| |
| System.out.println("writer2.book 变更后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
深拷贝
- 深拷贝和浅拷贝不同的,深拷贝中的引用类型字段也会克隆一份,当改变任何一个对象,另外一个对象不会随之改变
| class Book implements Cloneable{ |
| private String bookName; |
| private int price; |
| |
| |
| |
| @Override |
| public String toString() { |
| return super.toString().substring(26) + |
| " bookName='" + bookName + '\'' + |
| ", price=" + price + |
| '}'; |
| } |
| |
| |
| @Override |
| protected Object clone() throws CloneNotSupportedException { |
| return super.clone(); |
| } |
| } |
| class Writer implements Cloneable { |
| private int age; |
| private String name; |
| private Book book; |
| |
| |
| |
| @Override |
| public String toString() { |
| return "Writer{" + |
| "age=" + age + |
| ", name='" + name + '\'' + |
| ", book=" + book + |
| '}'; |
| } |
| |
| @Override |
| protected Object clone() throws CloneNotSupportedException { |
| |
| Writer writer = (Writer) super.clone(); |
| |
| writer.setBook((Book) writer.getBook().clone()); |
| return writer; |
| } |
| } |
| public static void main(String[] args) throws CloneNotSupportedException { |
| Writer writer1 = new Writer(18,"二狗",new Book("编译原理",100)); |
| Writer writer2 = (Writer) writer1.clone(); |
| |
| System.out.println("深拷贝后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| Book book = writer2.getBook(); |
| book.setBookName("离散数学"); |
| book.setPrice(70); |
| |
| System.out.println("writer2.book 变更后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
- 通过
clone()
方法实现的深拷贝比较笨重,因为要将所有的引用类型都重写 clone()
方法
使用序列化实现深拷贝
| class Book implements Serializable { |
| private String bookName; |
| private int price; |
| ... |
| } |
| class Writer implements Serializable { |
| private int age; |
| private String name; |
| private Book book; |
| |
| ... |
| |
| |
| public Object deepClone() throws IOException, ClassNotFoundException { |
| |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| ObjectOutputStream oos = new ObjectOutputStream(bos); |
| |
| oos.writeObject(this); |
| |
| |
| ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); |
| ObjectInputStream ois = new ObjectInputStream(bis); |
| |
| return ois.readObject(); |
| } |
| } |
| public static void main(String[] args) throws IOException, ClassNotFoundException { |
| Writer writer1 = new Writer(18, "二狗", new Book("编译原理", 100)); |
| Writer writer2 = (Writer) writer1.deepClone(); |
| |
| System.out.println("深拷贝后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| Book book = writer2.getBook(); |
| book.setBookName("离散数学"); |
| book.setPrice(70); |
| |
| System.out.println("writer2.book 变更后:"); |
| System.out.println("writer1:" + writer1); |
| System.out.println("writer2:" + writer2); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18301484
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步