1.檢查傳入參數的有效性,一般都會做個判斷是否NULL,或是不符合業務邏輯的要求,然後針對要求拋出異常或是其他處理。但是也要注意,如果業務上要求不是那麼嚴格,而且你判斷檢測的過程可能會消耗大量資源的時候,您應該權衡利弊一下。
2.需要的時候做保護性拷貝:
如:
import java.util.Date;
/**
*
*/
/**
* @author Administrator
*
*/
public final class Period {
private final Date start;
private final Date end;
public Period(Date start,Date end){
this.start=start;
this.end=end;
}
public Date start(){
return start;
}
public Date end(){
return end;
}
}
這樣一個類一看是非可變性的類,其實不然。當他的域Date有這樣情況時:
Date start=new Date();
Date end=new Date();
Period p=new Period(start,end);
end.setYear(78);
如果出現了其他客戶代碼修改了start或是end的數據時他就不是非可變的了。
但是我們可以把Period改成:
import java.util.Date;
/**
*
*/
/**
* @author Administrator
*
*/
public final class Period {
private final Date start;
private final Date end;
public Period(Date start,Date end){
this.start=new Date(start.getTime());
this.end=new Date(end.getTime());
if(this.start.compareTo(this.end)>0){
throw new IllegalArgumentException(start+"after "+end);
}
/*this.start=start;
this.end=end;*/
}
public Date start(){
return start;
}
public Date end(){
return end;
}
public static void main(String[] args){
Date start=new Date();
Date end=new Date();
Period p=new Period(start,end);
end.setYear(78);
}
}
這個樣的話就保證了end.setYear不會對p進行修改,因爲他做的值拷貝而不是賦值引用。這個是很經典的問題,有些時候要分析清除不然很容易導致一些引用和值的概念混淆問題。
大家還是會發現有問題引入這樣的情況也會被修改:
Date end=new Date();
Period p=new Period(start,end);
p.end().setYear(78);
這樣的做法就會造成問題的產生。因爲end()方法直接返回了成員內部的end的引用,造成了引用地址的不安全。但是我們也可以解決這個問題:
public Date start(){
return (Date)start.clone();
}
public Date end(){
return (Date)end.clone();
}
這樣我們拿到的就是真實的拷貝信息。而不是引用了。
經典的案例可以分享一下