保护性拷贝问题

为了防止类的约束条件受到来自类外部的破坏,在进行类设计时需要进行适当的保护性拷贝。下面举一个例子,设计了一个不可变的类Period:

public final class Period{

    private final Date start;
    private final Date end;

    public Period(Date start, Date end){
        if (start.compareTo (end)>0){
            throw new Illegal ArgumentException(start + " after”+end);
        }

        this.start = start;
        this.end = end;
    }

    public Date getStart() {
        return start;
    }

    public Date getEnd() {
        return end;
    }

}

Period类和其成员变量由final修饰,看上去不可变。但是如果在外部按照下面代码调用这个类,

Date start = new Date ();
Date end = new Date() ;
Period period = new Period ( start, end) ;
end.setYear(78);

其成员变量end仍然被改变,简单的拷贝并不能保证不可变,因此我们不得不将Period类的构造器作如下修改:

 public Period(Date start, Date end){
        this.start = new Date(start.getTime());
        this.end = new Date(end.getTime());

        if (start.compareTo (end)>0){
            throw new Illegal ArgumentException(start + " after”+end);
        }

        
    }

进行保护性拷贝后便无法在类的外部再修改成员变量的值。值得注意的是,将时间校验放在有效性拷贝之后可以防止在高并发情况下,参数在校验之后拷贝之前被修改。同时我们还得注意set函数和get,set函数的情况和上述构造器类似,同样修改即可。为了防止外部对象从get函数获得成员对象的实例,以getStart()为例将get函数修改为:

public Date getStart(){
    return new Date(start.getTime());
}

修改构造器和访问函数后,类Period真正成为不可变的类。

在编写代码的时候无论是向客户端提供的对象还是接受客户端的对象,又要考虑自身对象的安全性,防止发生不可预期的后果。例如,在使用Set和Map对象的时候,将对象作为key值时,就必须考虑到key被修改的情况。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值