(39):必要时进行保护性拷贝

看下面这个例子

public final class   Period

{
         private   final   Date   startTime;
         private   finale  Date   endTime;
         public   Period(Date  startTime , Date  endTime)

        {
               if(startTime.compareTo(endTime) > 0)
               { throw   new  IllegalArgumentException(“startTime  after  endTime !”);  }
                this.startTime = startTime;
                this.endTime  = endTime;
        }
        pubilc   Date   start()
        {  return   this.startTime ; }
        public   Date  end()
        { return  this.endTime  ; }

}
上面这段程序乍一看是不可变的,但事实上它有许多漏洞。
Date  startTime   =  new Date();
Date  endTime   = new  Date();
Period  per =  new  Period(startTime ,  endTime );
endTime.setYear(78);
我们通过改变Date类就可以改变Period,这时候我们就应该对构造器进行改造

public   Period(Date   startTime , Date  endTime )
{
      this.startTime  =  new Date (startTime.getTime());
      this.endTime   =  new  Date(endTime.getTime());
     if(this.startTime.compareTo(this.endTime)  >  0)
    { 
          throw   new    IllegalArgumentException(“startTime  after   endTime !”);
    }
}
但只是改变构造器也是不够的,start()、end()返回的Date也是可变的。如

per.start().setYear(78);
改造一下:

public  Date   start()
{
      return   new  Date(startTime.getTime());
}
public  Date  end()
{
      return  new   Date(endTime.getTime());
}
这样就真正实现了不可变。
保护性拷贝不仅仅只是针对不可变类。如果我们不能容忍对象进入数据结构后可以变化,我们也应该考虑保护性拷贝。

所以说我们应该尽量使用不可变的对象作为对象内部组件,这样就不必考虑保护性拷贝的问题了。

如果类具有从客户端得到或者返回客户端的可变组件,类就必须保护性地拷贝这些组件,如果拷贝成本受到限制,并且类信任调用者不会修改内部组件,不进行保护性拷贝也是可以的,类的文档必须清楚说明这一点。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值