问一个关于不要编写返回引用可变对象访问器方法的问题
源代码:public class EmployeeTest {
public static void main(String[] args)
{
Employee[] staff=new Employee[3];
staff[0]=new Employee( "carl cracker ",10000,1987,12,15);
staff[1]=new Employee( "harry hacker ",20000,1987,12,16);
staff[2]=new Employee( "tony tester ",30000,1987,12,17);
for(Employee e:staff)
e.raiseSalary(3);
for(Employee e:staff)
System.out.println( "name= "+e.getName()+ ",salary= "+e.getSalary()+ ",hireDay= "+e.getHireDay()+ ". ");
}
}
import java.util.*;
public class Employee {
private String name;
private double salary;
private Date hireDay;
public Employee(String n,double s,int year,int month,int day)
{
name=n;
salary=s;
GregorianCalendar calendar=new GregorianCalendar(year,month-1,day);
hireDay=calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public void raiseSalary(double percent)
{
double raise=salary*percent/100;
salary+=raise;
}
}
书上说不要编写返回引用可变对象的访问器方法。其中的getHireDay方法就违反了这个原则。应该改成:
public Date getHireDay()
{
return (Date)hireDay.clone();
}
那其中的方法getName不是返回了一个String类型的数据吗。是不是也应该改写getName方法。改写成:
public String getName()
{
return (String)name.clone();
}
是不是所有返回类对象的方法都要克隆,什么是引用可变的对象?
------解决方案--------------------String类是不可变的,返回的name如果你再次为它赋值,也不会改变原对象属性。
name= "abc ",将会使返回的这个引用指向一个新的对象 "abc ",这时再调用getName()得到的还是原来的值,不是 "abc "
不要编写返回引用可变对象的访问器方法
这是对的,不可变对象,比如Date类的对象的引用Date date=new Date();如果date是对象的属性,那么你在getHireDay()方法中返回了return date;那么我可以Date d=x.getHireDay();然后d.setHours(5);因为这个d和属性变量date引用的是同一个对象,那么那个private就白加了,我没有通过setHireDay()方法就改了它的值。
所以当需要返回可变对象的引用时要clone(),这是一个新对象,随便改,如果想改属性,那就调set方法。
但是String和java.lang包中的Integer,Byte等包装类都是不可变的,可以放心返回。