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

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,如果一个类想要实现克隆功能,需要实现Cloneable接口并重写clone()方法Cloneable接口是一个标记接口,没有任何方法需要实现,但它的存在告诉编译器这个类可以被克隆。 下面是一个示例代码,展示了如何在一个类中实现克隆功能: ```java public class MyClass implements Cloneable { private int number; public MyClass(int number) { this.number = number; } public int getNumber() { return number; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } ``` 在这个示例中,MyClass类实现了Cloneable接口,并且重写clone()方法。在clone()方法中,我们调用了父类的clone()方法来完成对象的浅拷贝。 要注意的是,clone()方法返回的是Object类型,需要进行类型转换才能得到具体的对象。 使用这个类进行克隆操作的示例代码如下: ```java public class Main { public static void main(String[] args) { MyClass obj1 = new MyClass(10); try { MyClass obj2 = (MyClass) obj1.clone(); System.out.println(obj2.getNumber()); // 输出 10 } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } ``` 在这个示例中,我们创建了一个MyClass对象obj1,并通过调用clone()方法创建了一个新的克隆对象obj2。最后打印出obj2的number属性,结果应该和obj1的number属性相同。 需要注意的是,这里的克隆是浅拷贝,即对象的引用属性不会被复制,而是仍然指向原始对象。如果需要实现深拷贝,即对象的所有属性都被复制一份,可以在clone()方法中进行相应的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值