现在有一个Employee类
class Employee {
private Date hireDate;
public Employee(Date date){
this.hireDate = date;
}
public Date getHireDate() {
return hireDate;
}
}
对属性封装后对外提供一个访问器方法,看起来没毛病对吧。
接下来我们获取一个初始化一个员工对象,并进行一番操作
Employee employee = new Employee(new Date());
System.out.println("新建时的员工发薪时间--->"
+ employee.getHireDate());
Date d = employee.getHireDate();
//设置时间为当前时间往前十年
d.setTime(d.getTime() - (long)10*365*24*60*60*1000);
System.out.println("修改引用d的发薪时间--->"+ d);
System.out.println("再次获取员工的发薪时--->:"
+ employee.getHireDate());
结果如下:
新建时的员工发薪时间—>Tue Apr 19 16:18:22 CST 2022
修改引用d的发薪时间—>Sat Apr 21 16:18:22 CST 2012
再次获取员工的发薪时—>:Sat Apr 21 16:18:22 CST 2012
我们发现我们并没有提供修改器方法,但是仅仅通过访问器方法,将获取到的对象进行一番修改,仍然可以修改employee员工的发薪时间,这是有问题的。
这是因为d和employee.hireDay引用的是同一个对象。(实际指向的是内存中的同一个对象)
虽然我们没法直接对hireDay进行修改,但是对d调用的更改器方法就可以自动的更改这个Employee对象的私有状态。
//这是Date类的setTime方法
public void setTime(long time) {
fastTime = time;
cdate = null;
}
如果以后碰到这种需要返回可变对象引用的访问器方法时,可以返回该属性的克隆。
public Date getHireDate() {
return (Date) hireDate.clone();
}
这样的话d其实指向的是另外一个对象了,无论怎么修改也不会影响到原始对象的属性了。