社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中
已经包含了一些有效值,此时可能会需要一个和A完全相同的新对象B,并且以
后对B任何改动都不会影响A中的值,也就是说A与B是两个独立的对象,但B的
初始值由A对象确定的. 在Java语言中用简单的赋值语句是不能满足这种需求的.
要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单的也是最高效的手段.
new操作符的本意是分配内存.程序执行到new操作符时,首先去看new操作符后面的类型,
因为知道了类型才能知道要分配多大的内存空间. 分配完内存以后,再调用构造函数,
填充对象的各个域. 这一步叫做初始化.构造方法返回后,一个对象创建完毕,
可以把它的引用(地址)发布到外部, 在外部就可以使用这个引用操作这个对象.
clone在第一步和new相似, 都是分配内存,调用clone方法时, 分配的内存
和原对象(调用clone方法的对象)相同, 然后再使用原对象中对应的各个域填充
新对象的域, 填充完成之后, clone方法返回一个新的相同的对象,同样可以把这
个新对象的引用发布到外部,就可以使用这个引用操作这个新对象.
定义一个Person对象类实现Cloneable接口重写clone()方法如下:
package com.ganbo; /** * Created by gan on 2018/3/13 17:18. */ public class Person implements Cloneable { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return super.toString(); } }
编写测试代码:
public static void main(String[] args) throws CloneNotSupportedException { Person p1 = new Person("Bruce", 23); Person p2 = (Person) p1.clone(); //克隆对象 System.out.println(p1 == p2); System.out.println(p1.getName() == p2.getName()); }
运行结果为:
false证明调用clone方法是克隆了一个新对象.
true表示p1和p2对象name属性其实还是同一个字符串对象. 这种调用克隆方法后属性并没有创建新对象叫
浅克隆.所以克隆方法执行调用的是浅拷贝,在编写程序的时候就要注意这个细节.
如果要想深拷贝一个对象,这个对象必须实现Cloneable接口,实现clone方法, 并且在clone方法内部要把
该对象的其他对象也要clone一份, 这就要求这个这个被引用的对象也必须要实现Cloneable接口并实现clone
方法. 那么如下代码所示:
package com.ganbo; /** * Created by gan on 2018/3/13 17:18. */ public class Person implements Cloneable { private Integer age; private Book book; public Person(Integer age, Book book) { this.age = age; this.book = book; } public void setAge(Integer age) { this.age = age; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public Integer getAge() { return age; } /** * 实现clone方法,并且在方法中把依赖的对象也clone一份 * * @return * @throws CloneNotSupportedException */ @Override protected Object clone() throws CloneNotSupportedException { Person newPerson = (Person) super.clone(); newPerson.book = (Book) book.clone(); return newPerson; } } class Book implements Cloneable { private Long id; public Book(Long id) { this.id = id; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
编写测试代码:
public static void main(String[] args) throws CloneNotSupportedException { Person p1 = new Person(23,new Book(12L)); Person p2 = (Person) p1.clone(); //克隆对象 System.out.println(p1.book == p2.book); }打印结果为:
完成深克隆.
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!