保护性拷贝(defensive copy)

何为保护性拷贝?看一个例子:

public class Person {


private String name;

private Date birth;


public Person(String name, Date birth) {

this.name = name;

this.birth = birth;

}


public Date getBirth() {

return birth;

}


public String getName() {

return name;

}

}


我们定义了一个Person类,该类的字段均为私有的,同时没有添加可以修改字段的方法(mutator)。这似乎就是一个不可变类(immutable class),事实真的是这样吗?我们来测试一下。

public static void main(String[] args) {


Person p = new Person("Benson",new Date(1990, 4, 13));

System.out.println(p.getName());

System.out.println(p.getBirth().getYear());


Date hole = p.getBirth();

hole.setYear(2013);


System.out.println(p.getName());

System.out.println(p.getBirth().getYear());

}


我们看看输出:

Benson

1990

Benson

2013


从输出可以看出该类并不是一个不可变类。因为该类的内部状态被修改了。问题出在哪呢?关键在于Date类是一个可变类(而String是一个不可变类,可放心使用),当我们在客户端获取Date类的实例引用时,如果就可以对其内部状态进行修改。如上代码所示。

 

一个解决办法就是使用保护性拷贝。

public class Person {


...

public Date getBirth() {

return new Date(birth.toString()); //保护性拷贝

}

...

}

 

这里我们修改了getBirth方法,返回一个同原来值相同的新对象。这样,即使客户端获得了该对象的引用,也无法修改person对象的内部状态,从而使该对象不可变。

 

再次运行测试类:​​​​​​​

Benson

1990

Benson

1990


Effective Java书中曾经指出,只要能够不创建对象,就不要创建多余的对象。另外一条是只要需要创建对象,就不要吝啬地创建它。它们并不矛盾,前者的目的是为了尽可能减少资源的占用,提高运行效率,后者是为了安全性。

 

reprint: https://blog.csdn.net/tounaobun/article/details/8607174

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值