Java面试问题之十八

阅读以下代码段,结合代码的意图分析此代码是否能够实现这个目的。



import java.util.Date;

public final class Schedule {
private final Date start; //开学时间,不允许被修改
private final Date end; //放假时间,不允许被修改

public Schedule(Date start,Date end){
if(start.compareTo(end)>0)
throw new IllegalArgumentException(start+" after "+end);
this.start=start;
this.end=end;
}

public Date getStart(){
return start;
}

public Date getEnd() {
return end;
}


}




问题分析:根据上述代码段可以看出,其意图是创建一个Schedule类,这个类包括了学校的开学时间和放假时间信息,并且想要其变成一个不可变类。但是,实际上这段代码并没有达到这个目的。它的开学时间和放假时间依然是可以被外部修改的。原因在于这个类没有实现保护性拷贝机制。在创建不可变类的时候,假定它的属性的类型是不可变类型,在必要的情况下,必须提供保护性拷贝,否则,这个不可变类实例的属性依然有可能被错误地修改。

为了保证Schedule对象的start属性和end属性值不会修改,这两个属性值必须使用保护性拷贝。例如:



import java.util.Date;

public final class Schedule {
private final Date start;
private final Date end;

public Schedule(Date start,Date end) {
if(start.compareTo(end)>0)
throw new IllegalArgumentException(start+" after "+end);
this.start=new Date(start.getTime()); //采用保护性拷贝
this.end=new Date(end.getTime()); //采用保护性拷贝
}

public Date getStart() {
return (Date)start.clone(); //采用保护性拷贝
}

public Date getEnd() {
return (Date)end.clone(); //采用保护性拷贝
}
}



通过采用保护性拷贝,其他程序无法获得与Schedule对象关联的两个Date对象的引用,因此也就无法修改这两个Date对象的属性值。
另外,如果Schedule类中被final修饰的属性所属的是不可变类,就没有必要提供保护性拷贝机制了,因为该属性所引用的实例的值永远都不会被改变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值