1.慎用異常。
異常對效能不利。拋出異常首先要建立一個新的對象。Throwable介面的建構函式調用名為fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法檢查堆棧,收集調用跟蹤資訊。只要有異常被拋出,VM就必須調整呼叫堆疊,因為在處理過程中建立了一個新的對象。異常只能用於錯誤處理,不應該用來控製程序流程。
2.不要重複初始設定變數。
預設情況下,調用類的建構函式時, Java會把變數初始化成確定的值:所有的對象被設定成null,整數變數(byte、short、int、long)設定成0,float和double變數設定成0.0,邏輯值設定成false。當一個類從另一個類派生時,這一點尤其應該注意,因為用new關鍵詞建立一個對象時,建構函式鏈中的所有建構函式都會被自動調用。
3.盡量使用局部變數。
調用方法時傳遞的參數以及在調用中建立的臨時變數都儲存在棧(Stack)中,速度較快。其他變數,如靜態變數、執行個體變數等,都在堆(Heap)中建立,速度較慢。另外,依賴於具體的編譯器/JVM,局部變數還可能得到進一步最佳化。
4.盡量指定類的final修飾符。
帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String。為String類指定final防止了人們覆蓋length()方法。另外,如果指定一個類為final,則該類所有的方法都是final。此舉能夠使效能平均提高50%。
5.不用new關鍵詞建立類的執行個體。
用new關鍵詞建立類的執行個體時,建構函式鏈中的所有建構函式都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。clone()方法不會調用任何類建構函式。
在使用設計模式(Design Pattern)的場合,如果用Factory模式建立對象,則改用clone()方法建立新的對象執行個體非常簡單。
6.字串聯接運算子+要慎用。
字串聯接運算子+看似簡單,但實際需要消耗大量系統資源。編譯器可高效地串連字串,但變數字串卻要求可觀的處理器時間。例如,假設s和t是字串變數:System.out.println("heading" + s + "trailer" + t);
上述語句要求建立一個StringBuffer(字串緩衝),追加自變數,然後用toString()將結果轉換回一個字串。因此,無論磁碟空間還是處理器時間,都會受到嚴重消耗。若準備追加多個字串,則可考慮直接使用一個字串緩衝——特別是能在一個迴圈裡重複利用它的時候。通過在每次迴圈裡禁止建立一個字串緩衝,可節省980單位的對象建立時間(如前所述)。利用substring()以及其他字串方法,可進一步地改善效能。如果可行,字元數組的速度甚至能夠更快。
7.慎用同步方法。
在JDK解譯器中,調用同步方法通常會比調用不同步方法慢10倍。所以要儘可能避免使用同步方法——若不能避免,方法的同步也要比代碼塊的同步稍快一些。
8.盡量使用Java的API類。
盡量使用來自Java API的類,因為它們本身已針對機器的效能進行了最佳化。這是用Java難於達到的。比如在複製任意長度的一個數組時,arraryCopy()比使用迴圈的速度快得多。