java重写clone()方法

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值