Java不可编写返回引用可变对象的访问器方法

问题:

使用java进行编程时,有时会发现在一个类中明明定义的是private类型,结果却能够在其他类中被修改。

代码:

class Employee
{
	private String name;
	private double salary;
	private Date hireDay;
	
	public Date getHireDay(){
		return hireDay;
	}

}
	Employee harry = new Employee("harry",75000,1987,12,15);
	Date d = harry.getHireDay();
	double tenYearsInMilliSeconds = 10 * 365.25 * 24 * 60 * 60 * 1000;
	d.setTime(d.getTime() - (long)tenYearsInMilliSeconds);
	System.out.println(harry.getHireDay());
按理说这里hireDay定义成了Date,此时打印输出的harry的雇佣日期应该是1987年,结果却是“Wed Dec 14 12:00:00 CST 1977”?!
出错的原因很微妙。d和harry.HireDay引用了同一个对象,对调用更改其方法就可以自动的改变这个雇员对象的私有状态。如果这里在main函数中更改引用的salary,就不会出现这个问题,如:
class Employee
{
	private String name;
	private double salary;
	private Date hireDay;
	
	public double getSalary(){
		return salary;
	}
}
	double test = harry.getSalary();
	test = 50;
	System.out.println(test);
	System.out.println(harry.getSalary());
打印结果:
50.0
75000.0

解决方法:

如果需要返回一个可变对象的引用,应该首先对它进行克隆。对象clone是指存放在另一个位置上的对象副本。下面是修改后的代码:
class Employee
{
	private String name;
	private double salary;
	private Date hireDay;

	public Date getHireDay(){
		return hireDay.clone();
	}
}
凭经验可知,如果需要返回一个可变数据域的拷贝,就应该使用clone。
这里有的同学可能会想到,如果hireDay用final修饰,是不是就解决了这个问题呢?然而事实并非如此,对于可变的类,使用final修饰符可能会对读者造成混乱。private final Date hireDay;仅仅意味着存储在hireDay变量中的对象引用在对象构造之后不能被改变,而并不意味着hireDay对象是一个常量。任何方法都可以对hireDay引用的对象调用setTime更改器。
参考:Java核心技术。




  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值