開心一笑
【1.別人復(fù)習(xí)都是無懈可擊,學(xué)渣復(fù)習(xí)是無中生有;
2.好了老師,我們各退一步,你們別講了,我們也不聽了;
3.少一點(diǎn)作業(yè),多一顆數(shù)木;少一次考試,多一片森林;保護(hù)環(huán)境人人有責(zé)......】
提出問題
項(xiàng)目中如何編寫通用程序???
解決問題

以下來自《Effective Java》中的讀書筆記:
將局部變量的作用域最小化
要是局部變量的作用域最小化,最有力的方法就是在第一次使用它的地方申明。
幾乎每個(gè)局部變量的聲明,都應(yīng)該包含一個(gè)初始化表達(dá)式。
下面是一種對(duì)局部變量的作用域進(jìn)行最小化的循環(huán)做法。
例如:
//防止每次循環(huán)都去調(diào)用size方法,提高性能
for(int i=0,len = userList.size();i < len;i++){
.....
}
最后一種將局部變量的作用域最小化的方法是使方法小而集中。(這個(gè)在之前的文章中已經(jīng)多次提到了)
for-each循環(huán)優(yōu)于傳統(tǒng)的for循環(huán)
例如:
//不推薦
for(Iterator i=c.iterator();i.hasNext()){
doSomething(i.next());
}
//推薦
for(Element e:c){
doSomething(e);
}
有三種情況無法使用for-each循環(huán):
- 過濾:如果需要遍歷集合。并刪除選定的元素,就需要使用顯示的迭代器,以便可以調(diào)用它的remove方法。
- 轉(zhuǎn)換:如果需要遍歷列表或者數(shù)組,并取代部分或者全部的元素值,就需要列表迭代器或者數(shù)組索引,以便設(shè)定元素的值。
- 平行迭代:如果需要并行的遍歷多個(gè)集合,就需要顯示的控制迭代器或者索引變量,以便所有迭代器或者索引變量都可以得到同步遷移。
了解和使用類庫
盡可能的使用第三方類庫。通過使用標(biāo)準(zhǔn)類庫,可以充分利用這些編寫標(biāo)準(zhǔn)類庫的專家的知識(shí),以及在你之前的其他人的使用經(jīng)驗(yàn)。
例如:
org.apache.commons.lang3
總而言之,不要重新發(fā)明輪子,如果你要做的事情看起來是十分常見的,有可能類庫中已經(jīng)有某個(gè)類完成了這樣的工作,如果確實(shí)是這樣,就使用現(xiàn)成的。如果還不清楚是否存在這樣的類,就去查一查。
如果需要準(zhǔn)確的答案,請(qǐng)避免使用float和double
float和double類型不適合用于貨幣計(jì)算,解決辦法是使用BigDecimal,int和long進(jìn)行貨幣計(jì)算。
總而言之,對(duì)于任何需要精確答案的計(jì)算任務(wù),請(qǐng)不要使用float或者double。
基本類型優(yōu)先于裝箱基本類型
基本類型:int,double,boolean等等
引用類型:String和List等等
裝箱基本類型:Integer,Double和Boolean等等
例如:
static Integer i;
public static void main(String[] args) {
//自動(dòng)拆箱,報(bào)NullPointerException異常
if(i == 42){
System.out.println("unbelievable");
}
}
當(dāng)在一項(xiàng)操作中混合使用基本類型和裝箱基本類型時(shí),裝箱基本類型就會(huì)自動(dòng)拆箱,這種情況無一例外。
上面問題就是修正i為int類型就好了。
例如:
//這個(gè)程序存在性能問題
public static void main(String[] args) {
Long sum = 0L;
for(long i=0;i<Integer.MAX_VALUE;i++){
//變量被反復(fù)的裝箱和拆箱,導(dǎo)致性能問題
sum += i;
}
System.out.println(sum);
}
那么什么時(shí)候應(yīng)該使用裝箱基本類型呢?
- 第一個(gè)是作為集合中的元素,鍵和值。
- 第二個(gè)是在參數(shù)化類型中,必須使用裝箱基本類型作為類型參數(shù)。
總之,當(dāng)可以選擇的時(shí)候,基本類型要優(yōu)先于裝箱基本類型?;绢愋透雍?jiǎn)單,也更加快速,如果必須使用,裝箱基本類型要特別小心。自動(dòng)裝箱減少了使用裝箱基本類型的繁瑣性,但是并沒有減少它的風(fēng)險(xiǎn)。當(dāng)程序用 == 操作符比較兩個(gè)裝箱基本類型時(shí)。他做了個(gè)同一性比較,這幾乎肯定不是你所希望的。當(dāng)程序進(jìn)行涉及裝箱和拆箱基本類型的混合類型計(jì)算時(shí),他會(huì)進(jìn)行拆箱。當(dāng)程序進(jìn)行拆箱時(shí),會(huì)拋出空指針異常。最后當(dāng)程序裝箱了基本類型值時(shí),會(huì)導(dǎo)致高開銷和不必要的對(duì)象創(chuàng)建。
如果其它類型更適合,則盡量避免使用字符串
- 字符串不適合代替其他的值類型,數(shù)值類型應(yīng)當(dāng)被適當(dāng)?shù)剞D(zhuǎn)換為數(shù)值類型,比如int,float或者double,布爾類型就應(yīng)該被轉(zhuǎn)化為boolean類型等等。
- 字符串不適合代替枚舉類型。
例如:
String compounKey = className + "#" + i.next();
缺點(diǎn):如果用來分隔的字符也出現(xiàn)在某個(gè)域中,結(jié)果就會(huì)出現(xiàn)混亂。
- 字符串不適合代替聚集類型。(不可偽造的鍵有時(shí)候被稱為能力)
例如:
//有問題,在線程中,如果客戶傳入key相同,安全性就很差
public static set(String key,Object value){
}
public static Object get(String key){
}
改正:
public static class Key{
Key(){}
}
public static Key getKey(){
return new Key();
}
//重點(diǎn)在這里哦,使用對(duì)象Key哦
public static void set(Key key,Object value);
public static Object get(Key key);
當(dāng)心字符串連接的性能
對(duì)于大規(guī)模的場(chǎng)景中,為連接n個(gè)字符串而重復(fù)的使用字符串連接操作符,需要n的平方級(jí)的時(shí)間。
具體的詳細(xì)內(nèi)容,請(qǐng)看之前的這篇文章:
優(yōu)雅編程之這樣考慮字符性能,你就“正?!绷耍ǘ?/a>
通用接口引用對(duì)象
例如:
//正確
List<Subscribe> subscribes = new Vector<>();
//欠缺
Vector<Subscribe> subscribes = new Vector<>();
當(dāng)你決定更換實(shí)現(xiàn)時(shí),所要做的就只是改變構(gòu)造器中類的名稱。
List<Subscribe> subscribes = new ArrayList<>();
周圍的所有代碼都可以繼續(xù)工作。
但是
如果沒有合適的接口存在,完全可以用類,而不是接口來引用對(duì)象。例如考慮值類,比如String和BigInteger。記住,值類很少會(huì)用多個(gè)實(shí)現(xiàn)編寫。它們通常是final
類實(shí)現(xiàn)了接口,但是它提供了接口中不存在的額外方法,如果程序依賴于這些額外的方法,這種類就應(yīng)該只被用來引用它的實(shí)例,它很少應(yīng)該被用作參數(shù)類型。
接口優(yōu)先于相射機(jī)制
反射機(jī)制需要付出代價(jià):
- 喪失了編譯時(shí)類型檢查的好處:如果程序企圖用反射方式調(diào)用不存在或不可訪問的方法,在運(yùn)行時(shí)它將會(huì)失敗。
- 執(zhí)行反射訪問所需要的代碼非常笨拙和冗長(zhǎng)。
- 性能損耗。反射方法調(diào)用的比普通方法調(diào)用慢了很多。
通常普通應(yīng)用程序在運(yùn)行時(shí)不應(yīng)該以反射方式訪問對(duì)象。
謹(jǐn)慎地使用本地方法
Java Native Interface(JNI)允許Java程序可以調(diào)用本地方法(native method)
使用本地方法來提高性能的做法不值得提倡。
使用本地方法有一些嚴(yán)重的缺點(diǎn)。因?yàn)楸镜卣Z言不是安全的
謹(jǐn)慎的進(jìn)行優(yōu)化
有三條與優(yōu)化相關(guān)的格言是每個(gè)人都應(yīng)該知道的。
很多計(jì)算機(jī)上的過失都被歸咎于效率(沒有必要達(dá)到的效率),而不是任何其他的原因,甚至包括盲目地做傻事。
不要去計(jì)較效率上的一些小小的得失,在97%的情況下,不成熟的優(yōu)化才是一切問題的根源。
在優(yōu)化方面,我們應(yīng)該遵守2條原則:1.不要進(jìn)行優(yōu)化。2.(僅針對(duì)專家)還是不要進(jìn)行優(yōu)化,也就是說,在你還沒有絕對(duì)清晰的未優(yōu)化方案之前,請(qǐng)不要進(jìn)行優(yōu)化。
總之,不要費(fèi)力去編寫快速程序,應(yīng)該努力編寫好的程序,速度自然會(huì)隨之而來。
普遍接受的命名慣例
-
包名稱:一個(gè)或者多個(gè)包的簡(jiǎn)短名稱組成,每個(gè)簡(jiǎn)短名稱通常不超過8個(gè)字符(事實(shí)發(fā)現(xiàn),JDK上的包也些也超過8個(gè)字符:java.awt.datatransfer )。所以作者在這里使用通常,也就是有例外
java.applet
java.awt
java.awt.color 類和接口名稱,包括枚舉和注解名稱:通常由一個(gè)或者多個(gè)單詞組成,每個(gè)單詞的首字母大寫(TimerTask),盡量避免縮寫,除非類似這種:max或者min
方法和域的名稱:與類和接口名稱類似,只是方法首字母小寫。方法的名稱一般由動(dòng)詞或者動(dòng)詞,名稱組成。如:remove,removeUser等等
常量:如:public static final int MIN_VALUE,全部大寫,中間用下劃線分割
局部變量名稱與成員變量的名稱類似,只不過它允許縮寫
類型參數(shù)名稱:通常由單個(gè)字母組成,T表示任意類型,E表示集合元素類型,K,V表示鍵和值,X表示異常
讀書感悟
來自《鄰室的音樂》
- 窮是一種心態(tài),你若一輩子堅(jiān)持自己是窮人,擁有大量金錢也救不了你。
- 凡是太好的東西都不像真的。又有人說,如果一件事好得不似真的,可能它的確不是真的。
- 人生試題一共四道題目。學(xué)業(yè)事業(yè)婚姻家庭,平均分高才能及格,切莫花太多時(shí)間在任何一題上。
- 真正聰明的女子該是懂得利用自己的智慧享受生命,而不僅僅是為了那點(diǎn)生不帶來死不帶去的利益。這點(diǎn)沒有想通,便失去了自我,失去了珍貴的友誼。
其他
如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎轉(zhuǎn)載,點(diǎn)贊,頂,歡迎留下寶貴的意見,多謝支持!