实现克隆的方式-实现Cloneable接口
- 如果实现Cloneable接口之后,不重写clone()方法;默认使用的是Object的clone方法
- 如果重写,方式如下:
/**
* clone的实现方式
* @author zouruihuisz
* @version v1.0
* @date 2024/8/11
*/
public class CloneObjectTest implements Cloneable {
String name;
int age;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "CloneObjectTest{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
CloneObjectTest cloneObjectTest = new CloneObjectTest();
cloneObjectTest.age = 18;
cloneObjectTest.name = "zhangsan";
try {
CloneObjectTest clone = (CloneObjectTest) cloneObjectTest.clone();
clone.age=19;
clone.name="zrhsmile";
System.out.println("原来的类:"+cloneObjectTest);
System.out.println("clone之后的类: "+clone);
System.out.println(cloneObjectTest==clone);
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
- 在clone中,如果是基本类型和String类型,复制之后因为是新的对象,修改值之后不会对原对象有影响;
- 如果是有引用类型,clone对象更改引用对象之后;也会对原来对象的引用类型的对象有影响。
浅克隆
浅克隆就是类实现Cloneable接口,并重写clone方法【不重写,默认使用的Object的clone方法】
深克隆
- 如果类中有其他应用类型;引用类型的类也要实现Cloneable接口; 并重写clone方法
- 通知,在本类中的clone方法,也要对引用类型进行clone方法的调用
代码如下:
package com.kingreda.cn.clone;
/**
* 深克隆
* @author zouruihuisz
* @version v1.0
* @date 2024/8/11
*/
public class Person implements Cloneable{
private String name;
private Integer age;
/**
* 引用类型Address
*/
private Address add;
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;
}
public Address getAdd() {
return add;
}
public void setAdd(Address add) {
this.add = add;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", add=" + add +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 浅克隆
Person person = (Person) super.clone();
// 深克隆(引用类型Address也要进行clone)
person.setAdd((Address) add.clone());
return person;
}
public static void main(String[] args) {
// 要clone的对象
Person person = new Person();
Address address =new Address();
address.setAddr("北京市");
person.setAdd(address);
person.setName("tom");
person.setAge(19);
try {
// 克隆之后的对象
Person clone = (Person)person.clone();
// 修改属性值
clone.setAge(20);
clone.setName("sudi");
// 修改地址属性
clone.getAdd().setAddr("上海市");
System.out.println(person);
System.out.println(clone);
// 判断clone前后的地址是否相等
System.out.println(person.getAdd() == clone.getAdd());
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
class Address implements Cloneable{
private String addr;
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Address{" +
"addr='" + addr + '\'' +
'}';
}
}
总结
- 浅克隆是实现Cloneable接口,并重写clone方法;
- 深克隆,是类中引用类型也要实现Cloneable接口,并重写clone方法; 同时,在类中的clone方法中,设置引用类型属性时,也要调用引用类型的clone方法;
- 如果是基本类型和String类型,使用浅克隆即可;
- 如果有引用类型, 则使用深克隆;