源代码: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();
}
是不是所有返回类对象的方法都要克隆,什么是引用可变的对象?

解决方案 »

  1.   

    浅clone和深clone的问题,没看明白
      

  2.   

    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等包装类都是不可变的,可以放心返回。
      

  3.   

    你看的是Java核心技术吧,我也看了这里
      

  4.   

    to jackeyhz(愚公移山) 从贴主的描述来看,书上没有错。Date作为一个可变对象,所谓可变,是指可以通过各种方法改变它的内部状态。
    所以,为了维持自己的Date对象保持不变,应该返回一个clone的对象给客户。
    而String则不同,它本身是个不可变的类,因此,没有必要使用clone再返回。
      

  5.   

    呵呵,好熟悉的代码~
    楼上说的正解.
    String这个类很特殊,有好多问题都是它引起的.
    看到一个String的时候要一只眼睛把他当类看,一只眼睛把他当字面常量看.