clone()
在使用clone之前看一下=复制一个类是咋样的。
Address address=new Address("中国","浙江","杭州");
Person p=new Person("张三",24,address);
Person p2=p;
即用=复制一个类之后,会产生一个新的对象,然后二者都指向,堆内存中的对象,
且通过任意一个引用修改对象,二者都会发生变化,因为都是指向同一个对象。
接下来看clone
记住要对clone进行重写,重写规则为 :实现接口class Person implements Cloneable
clone 源代码
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
重写规则:
protected Person clone() {// throws CloneNotSupportedException 写到下面
//return (Person)super.clone();
Person p=null;
try{
p=(Person)super.clone();
}catch(CloneNotSupportedException e){
throw new RuntimeException(e);
//e.printStackTrace();
}
return p;
}
浅克隆
//浅克隆
public class TestClone1 {
public static void main(String[] args) {
Address address=new Address("中国","浙江","杭州");
Person p=new Person("张三",24,address);
System.out.println("原类"+p.printPerson());
Person p1=p.clone();//如果常规alt+ins调出clone 要重写clone
System.out.println("克隆类"+p1.printPerson());
System.out.println("原类地址:"+p+'\n'+"克隆类地址:" +p1);
System.out.println("修改克隆类");
p1.setName("李四");
p1.setAge(23);
p1.getAddress().setCountry("China");
p1.getAddress().setProvince("jiangxi");
p1.getAddress().setCity("jiujiang");
System.out.println("原类"+p.printPerson());
System.out.println("修改后 克隆类"+p1.printPerson());
System.out.println("原类地址:"+p+'\n'+"克隆类地址:" +p1);
}
}
class Address{
private String country;
private String province;
private String city;
public Address(String country, String province, String city) {
this.country = country;
this.province = province;
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String print1() {
return "{" +
"country='" + country + '\'' +
", province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
class Person implements Cloneable{
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String printPerson() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address.print1() +
'}';
}
@Override
protected Person clone() {// throws CloneNotSupportedException 写到下面
//return (Person)super.clone();
Person p=null;
try{
p=(Person)super.clone();
}catch(CloneNotSupportedException e){
throw new RuntimeException(e);
//e.printStackTrace();
}
return p;
}
}
上述中可以克隆出一个新的对象p1,修改p1,p的实例变量不会发生改变,即name 和age,但是Address这种引用数据类型的数据变量会一起发生改变,这就是说明克隆失败了,修改的是同一个address,这称为浅克隆,如果想在修改克隆类的同时,不修改原类的address,那么需要深克隆。
即浅克隆,是在堆内存生成了一个新的对象Person,(这时候有两个Person对象)但是! 引用数据类型class的对象Address,他们是共用一个,所以,通过引用修改其中任何一个,另外一个引用指向的Address对象也会变。
深克隆
针对类使用的引用数据类型在修改的时候也会被修改
所以要在引用数据类型中重写clone方法
class Address implements Cloneable
重写
@Override
protected Address clone() {//再在Person类的clone方法里加一个 Person.address=addreee.clone()
// super.clone();
Address add=null;
try{
add=(Address)super.clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();;
}
return add;
}
再在person 类的重写clone方法中
加一句p.address=address.clone();
//浅克隆
public class TestClone1 {
public static void main(String[] args) {
Address address=new Address("中国","浙江","杭州");
Person p=new Person("张三",24,address);
System.out.println("原类"+p.printPerson());
Person p1=p.clone();//如果常规alt+ins调出clone 要重写clone
System.out.println("克隆类"+p1.printPerson());
System.out.println("原类地址:"+p+'\n'+"克隆类地址:" +p1);
System.out.println("修改克隆类");
p1.setName("李四");
p1.setAge(23);
p1.getAddress().setCountry("China");
p1.getAddress().setProvince("jiangxi");
p1.getAddress().setCity("jiujiang");
System.out.println("原类"+p.printPerson());
System.out.println("修改后 克隆类"+p1.printPerson());
System.out.println("原类地址:"+p+'\n'+"克隆类地址:" +p1);
}
}
class Address implements Cloneable{
private String country;
private String province;
private String city;
public Address(String country, String province, String city) {
this.country = country;
this.province = province;
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String print1() {
return "{" +
"country='" + country + '\'' +
", province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
@Override
protected Address clone() {//再在Person类的clone方法里加一个 Person.address=addreee.clone()
// super.clone();
Address add=null;
try{
add=(Address)super.clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();;
}
return add;
}
}
class Person implements Cloneable{
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String printPerson() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address.print1() +
'}';
}
@Override
protected Person clone() {// throws CloneNotSupportedException 写到下面
//return (Person)super.clone();
Person p=null;
try{
p=(Person)super.clone();
p.address=address.clone();
}catch(CloneNotSupportedException e){
throw new RuntimeException(e);
//e.printStackTrace();
}
return p;
}
}
所以潜克隆和深克隆针对引用数据类型,如果有引用数据类型,那么要在引用数据类型中重写clone,才可以实现,修改克隆的,原类不受影响,否则引用数据类型的类数据将受牵连。
参考1
参考2