java对象克隆详解

先来看一下为一个包含对象引用的变量建立副本时会发生什么。原变量和副本都是同一个对象的引用,如图,这说明,任何一个变量改变都会影响另一个变量。

 

Employee original = new Employee("John Public", 50000)
Employee copy = original;
copy.raiseSalary(10); // oops--also changed original

如果希望copy是一个新对象,它的初始状态与original相同,但是之后它们各自会有自己不同的状态,这种情况下就可以使用clone方法。

Employee copy = origin.clone();
copy.raiseSalary(10);    // ok -- original unchanged

实例:

以下程序克隆了Employee类的一个实例,然后调用两个更改器方法。raiseSalary方法会改变salary域的值,而setHireDay方法改变hireDay域的状态。这两个更改器方法都不会影响原来的对象,因为clone是一个深拷贝。

Employee:

import java.util.Date;
import java.util.GregorianCalendar;

public class Employee07 implements Cloneable{
    // cloneable : 标记接口
    private String name;
    private double salary;
    private Date hireDay;

    public Employee07(String name, double salary) {
        this.name = name;
        this.salary = salary;
        hireDay = new Date();
    }

    public Employee07 clone() throws CloneNotSupportedException {
        // call object.clone()
        Employee07 cloned = (Employee07) super.clone();

        // clone mutable fields
        cloned.hireDay = (Date) hireDay.clone();
        return cloned;
    }

    /**
     * set the hire day to a given date
     * @param year the year of the hire day
     * @param month the month of the hire day
     * @param day the day of the hire day
     */
    public void setHireDay(int year, int month, int day) {
        Date newHireDay = new GregorianCalendar(year, month-1,day).getTime();
        //Example of instance field mutation
        hireDay.setTime(newHireDay.getTime());
    }

    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }

    public String toString() {
        return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
    }
}

CloneTest:

public class CloneTest {
    public static void main(String[] args) {
        try {
            Employee07 original = new Employee07("John. public",50000);
            original.setHireDay(2000,1,1);
            Employee07 copy = original.clone();
            copy.raiseSalary(10);
            copy.setHireDay(2020,6,1);
            System.out.println("original="+original);
            System.out.println("copy="+copy);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值