開心一笑
【一大哥去醫(yī)院看病。
醫(yī)生問:你得了什么???
大哥說: 我得了間接性失憶癥。
醫(yī)生問:具體什么癥狀?
大哥說:我一看到漂亮的姑娘就忘記自己已結(jié)婚了。
醫(yī)生說:滾滾滾,這病我自己都沒治好!】
提出問題
項目開發(fā)中,使用方法要注意的一些事項???
解決問題

以下來自《Effective Java》中的讀書筆記:
檢查參數(shù)有效性
應(yīng)該在發(fā)生錯誤之后盡快檢測出錯誤
例如:
public BigInteger mod(BigInteger m){
//盡快檢查錯誤
if(m.signum() <= 0){
throw new ArithmeticException("Modulus <= 0:" + m);
}
....
}
非共有的方法通常應(yīng)該使用斷言來檢查它們的參數(shù),具體做法如下:
private static void sort(long a[],int offset,int length){
assert a != null;
assert offset >= 0 && offset <= a.length;
assert length >=0 && length <=a.length -offset;
....//dosomethiing
}
必要時進行保護性拷貝
對于構(gòu)造器的每個可變參數(shù)進行保護性拷貝是必要的
例如:
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 start = new Date();
Date end = new Date();
Period p = new Period(start,end);
//注意問題出現(xiàn)在這里
end.setYear(78);
修改后:
public Period(Date start,Date end){
....
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
}
注意,保護性拷貝是在檢查參數(shù)有效性之前進行的,并且有效性檢查是針對拷貝之后的對象,而不是針對原始的對象。
雖然替換構(gòu)造器就可以成功避免上述攻擊,但是改變Period實例仍然是有可能的,例如下面例子:
Date start = new Date();
Date end = new Date();
Period p = new Period(start,end);
//注意問題出現(xiàn)在這里
p.end().setYear(78);
進一步修改:
public Date start(){
return new Date(start.getTime());
}
public Date end(){
return new Date(end.getTime());
}
簡而言之,如果類具有從客戶端得到或者返回到客戶端的可變組件,類就必須保護性的拷貝這些組件。如果拷貝的成本受到限制,并且內(nèi)信任它的客戶端不會不恰當?shù)男薷慕M件,就可以在文檔中指明客戶端的職責是不得修改受到影響的組件,以此來代替保護性拷貝。
謹慎設(shè)計方法簽名
- 謹慎地選擇方法的名稱。
- 不要過于追求提供便利的方法。
- 避免過長的參數(shù)列表。
有三種方法可以縮短過長的參數(shù)列表,第一種是把方法分解成多個方法,每個方法只需要這些參數(shù)的一個子集。第二種方法是創(chuàng)建輔助類用來保存參數(shù)的分組。第三種是如果方法帶有多個參數(shù),尤其是當它們中有些是可選的時候,最好定一個對象來表示所有參數(shù)。(這些在之前文章都有提過了)
慎用可變參數(shù)
在重視性能的情況下,使用可變參數(shù)需要特別小心,可變參數(shù)方法的每次調(diào)用都會導(dǎo)致進行一次數(shù)組分配和初始化。如果憑經(jīng)驗確定無法承受這一成本,但又需要可變參數(shù)的靈活性,還有一種模式可以讓你如愿以償。假設(shè)確定對某個方法95%的調(diào)用會有3個或者更少的參數(shù),就聲明改方法的5個重載,每個重載方法帶有0至3個普通參數(shù),當參數(shù)的數(shù)目超過3個時,就使用一個可變參數(shù)方法:
例如:
public void foo(){}
public void foo(int a1){}
public void foo(int a1,int a2){}
public void foo(int a1,int a2,int a3){}
public void foo(int a1,int a2,int a3,int ... rest){}
這種方法可能不太恰當,但是一旦需要它時,它可就幫上大忙了。
總之,在定義參數(shù)數(shù)目不定的方法時,可變參數(shù)方法是一種很方便的方式,但是它們不應(yīng)該被過度濫用。如果使用不當,會產(chǎn)生混亂的結(jié)果。
返回零長度的數(shù)組或集合,而不是null
例如:
public Cheese[] getCheeses(int size){
if(size == 0){
//這里返回null,是錯誤的,因為調(diào)用改方法,還需要判斷這個null對象
return null;
}
}
正確做法:
private final List<Cheese> cheesesInStock = ...;
//定義final型的空數(shù)組
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses(){
//返回空數(shù)組而不是null
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
同樣的對于集合(Collections.emptySet,emptyList,emptyMap等等)
public List<Cheese> getCheesesList(){
if(cheesesInStock.isEmpty()){
//返回不可變的空集合,對于map
return Collections.emptyList();
}else{
return new ArrayList<Cheese>(cheesesInStock);
}
}
有時候會有人認為:null返回值比零長度數(shù)組更好,因為他避免了分配數(shù)組所需要的開銷。
為所有導(dǎo)出的API元素編寫文檔注釋
例如:
/**
* <p> the method is ...<i>not<i>
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc} if the index is out of..
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
方法的文檔注釋中每個參數(shù)都有一個@param標簽(后面應(yīng)該是一個名詞),以及一個@return標簽(除非返回為空),以及@throws標簽(后面應(yīng)該是一個名詞),@throws標簽后應(yīng)該包含單詞"if",描述了異常將在什么樣的條件下會被拋出。
文檔注釋還使用了HTML標簽(<p>和<i>).Javadoc工具會把文檔注釋翻譯成HTML
**{@code} **:表示該代碼片段以代碼字體進行呈現(xiàn)
{@literal}:可以把小于號,大于號等包起來,用來輸出這些字符。
更多的文檔注釋,可以看《Effective Java》對它的描述。
讀書感悟
來自亦舒《不易居》
- 現(xiàn)在還有誰會照顧誰一輩子,那是多沉重的一個包袱。所以非自立不可。
- 你要改是因為你自己愿意改,不要為任何人,怕只怕那人會令你失望,你又得打回原形。
其他
如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎轉(zhuǎn)載,點贊,頂,歡迎留下寶貴的意見,多謝支持!