陳俟伶 重慶工程學院
1.1 不要導入一些不使用的類,不要創建一些不使用的對象
這毫無意義,如果代碼中出現”The value of the local variable i is not used”、”The import java.util is never used”,那么請刪除這些無用的內容。
1.2 盡量指定方法、類的final修飾符
帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String,整個類都是final的。為類指定final修飾符可以讓類不可以被繼承,為方法指定final修飾符可以讓方法不可以被重寫。如果指定了一個類為final,則該類所有的方法都是final的。Java編譯器會尋找機會內聯所有的final方法,內聯對于提升Java運行效率作用重大,具體參見Java運行期優化。這樣可以使性能平均提高50%。
1.3 盡量使用局部變量
調用方法時傳遞的參數以及在調用中創建的臨時變量都保存在棧中速度較快,其他變量,如靜態變量、實例變量等,都在堆中創建,速度較慢。另外,棧中創建的變量,隨著方法的運行結束,這些內容就沒了,不需要額外的垃圾回收。
1.4 將常量聲明為static final,并以大寫命名
這樣在編譯期間就可以把這些內容放入常量池中,避免運行期間計算生成常量的值。另外,將常量的名字以大寫命名也可以方便區分出常量與變量
1.5 盡量減少對變量的重復計算
明確一個概念,對方法的調用,即使方法中只有一句語句,也是有消耗的,包括創建棧幀、調用方法時保護現場、調用方法完畢時恢復現場等。所以例如下面的操作:
for (int i = 0; i < list.size();i++ )
建 議 替 換 為:for (int i = 0, int length = list.size(); i
這樣,在list.size()很大的時候,就減少了很多的消耗
1.6 盡量采用懶加載的策略,即在需要的時候才創建
例如:String str = "aaa";if (i == 1) { list.add(str); }
建議替換為:if (i == 1) { String str = "aaa"; list.add(str); }
1.7 循環內不要不斷創建對象引用
例 如:for (int i = 1; i < count;i++){Object obj =new Object();}
這種做法會導致內存中有count份Object對象引用存在,count很大的話,就耗費內存了,建議為改為:Object obj = null;for (int i = 1; i 這樣的話,內存中只有一份Object對象引用,每次new Object()的時候,Object對象引用指向不同的Object罷了,但是內存中只有一份,這樣就大大節省了內存空間了。 1.8 使用同步代碼塊替代同步方法 除非能確定一整個方法都是需要進行同步的,否則盡量使用同步代碼塊,避免對那些不需要進行同步的代碼也進行了同步,影響了代碼執行效率。 1.9 不要讓public方法中有太多的形參 方法太多形參的話主要有兩點壞處:一是違反了面向對象的編程思想,Java講求一切都是對象,太多的形參,和面向對象的編程思想并不契合。二是參數太多勢必導致方法調用的出錯概率增加。 1.10 把一個基本數據類型轉為字符串,基本數據類型.toString()是最快的方式、String.valueOf(數據)次之、數據+””最慢。 1.11 盡量使用HashMap、ArrayList、StringBuilder,除非線程安全需要,否則不推薦使用Hashtable、Vector、StringBuffer,后三者由于使用同步機制而導致了性能開銷。 1.12 如果能估計到待添加的內容長度,為底層以數組方式實現的集合、工具類指定初始長度 比 如 ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSet等等。 1.13 順序插入和隨機訪問比較多的場景使用ArrayList,元素刪除和中間插入比較多的場景使用LinkedList 1.14 使用最有效率的方式去遍歷Map 遍歷Map的方式有很多,通常場景下我們需要的是遍歷Map中的Key和Value,那么推薦使用的、效率最高的方式是: HashMap map =new HashMap(); map.put("001", " 張三 "); Set set = map.entrySet(); Iterator it = set.iterator(); while(it.hasNext()) { Map.Entry entry = it.next(); System.out.println(entry.getKey() + " " + entry.getValue()); } 如果你只是想遍歷一下這個Map的key值,那用”Set set = map.keySet();”會比較合適一些。 1.15 不要在循環中使用try…catch…,應該把其放在最外層 1.16 使用帶緩沖的輸入輸出流進行IO操作 帶 緩 沖 的 輸 入 輸 出 流,即 BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,這可以極大地提升IO效率 1.17 及時關閉流 Java編程過程中,進行數據庫連接、I/O流操作時務必小心,在使用完畢后,及時關閉以釋放資源。因為對這些大對象的操作會造成系統大的開銷,稍有不慎,將會導致嚴重的后果。 1.18 對資源的close()建議分開操作 例如:try{ XXX.close(); YYY.close(); }catch (Exception e) {...} 建議修改為:try{ XXX.close(); }catch (Exception e) {... }try{YYY.close(); }catch (Exception e) {... }雖然有些麻煩,卻能避免資源泄露。優化前,如果XXX.close()拋異常了,那么就進入了cath塊中了,YYY.close()不會執行,YYY這塊資源就不會回收了,一直占用著,這樣的代碼一多,是可能引起資源句柄泄露的。而優化后,就保證了無論如何XXX和YYY都會被close掉。 代碼優化,一個很重要的課題。可能有些人覺得沒用,一些細小的地方有什么好修改的,改與不改對于代碼的運行效率有什么影響呢?這個問題我是這么考慮的,就像大海里面的鯨魚一樣,它吃一條小蝦米有用嗎?沒用,但是,吃的小蝦米一多之后,鯨魚就被喂飽了。代碼優化也是一樣,如果項目著眼于盡快無BUG上線,那么此時可以抓大放小,代碼的細節可以不精打細磨;但是如果有足夠的時間開發、維護代碼,這時候就必須考慮每個可以優化的細節了,一個一個細小的優化點累積起來,對于代碼的運行效率絕對是有提升的。2. 結束語