java代碼優(yōu)化總結(jié)

上次面試的時(shí)候,免面試官問我java代碼優(yōu)化,雖然平時(shí)在實(shí)際開發(fā)中也有注意這方面的問題,但當(dāng)時(shí)就是沒回來上來,都怪平時(shí)沒注意總結(jié),所以今天就在這里總結(jié)。這里我還要提醒下那些新手,想學(xué)好一門技能,總結(jié)非常重要。好記性不如爛筆頭。好了廢話不多說了。

1.盡量減少對變量的重復(fù)計(jì)算

使用帶下標(biāo)的for循環(huán)時(shí),如下所示:
List<String> list = new ArrayList<>();
...
for(int i = 0; i < list.size(); i++) {
}

這種情況下,最好把對size的計(jì)算放到循環(huán)外,因?yàn)檫@樣每次遍歷都會(huì)計(jì)算一次,造成了不必要的浪費(fèi)。改成如下:

List<String> list = new ArrayList<>();
...
int size;
for(int i = 0; i < size = list.size(); i++) {
}
獲取方法參數(shù)的值時(shí),對值的獲取盡量只有一次(即,使用get()方法獲?。?。這樣做后你的參數(shù)引用只有一個(gè),維護(hù)更加方便。

2. 如果事先知道容器的容量,初始化時(shí)盡量指定它的初始容量(initialCapacity)

例如Map可以這樣指定

Map<String, Object> map = new HashMap<>(2);

3. 計(jì)算時(shí)盡量使用位運(yùn)算

例如對一個(gè)數(shù)乘/除一個(gè)偶數(shù),如下:

int a = 5;
int b = a * 4;
int c = a / 4;

改為:

int a = 5;
int b = a << 2; //右移兩位
int c = a >> 2;//左移兩位

4. int轉(zhuǎn)String,盡量使用String.valueOf();不要使用+ ""+ ""在底層會(huì)使用StringBuilderappend()方法,最后調(diào)用toString()。這里貼上javap后的源碼:

    @Test
    public void test1() {
        int a = 5;
        String s = a + "";
    }

javap -c 后的源碼:

  public void test1();
    Code:
       0: iconst_5
       1: istore_1
       2: new           #2                  // class java/lang/StringBuilder
       5: dup
       6: invokespecial #3                  // Method java/lang/StringBuilder."<init>":()V
       9: iload_1
      10: invokevirtual #4                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      13: ldc           #5                  // String
      15: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      18: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      21: astore_2
      22: return

還是做了很多操作的。接下來我們看看String.valueOf()方法:

    @Test
    public void test1() {
        int a = 5;
        String s = String.valueOf(a);
    }

javap -c 后的源碼:

  public void test1();
    Code:
       0: iconst_5
       1: istore_1
       2: iload_1
       3: invokestatic  #2                  // Method java/lang/String.valueOf:(I)Ljava/lang/String;
       6: astore_2
       7: return

不多說了,很明顯的變化。

所以盡量使用String.valueOf()

5. 對變量的聲明盡量放到條件語句內(nèi)(盡量采用懶加載的策略,即在需要的時(shí)候才創(chuàng)建)

public void printB(int a){
  int b = 2;
  if (a == 1) {
    System.out.println(b);
  }
}

這時(shí)的System.out.println(b);a不等于1時(shí),是不會(huì)被執(zhí)行的,所以因該把b變量的聲明放到條件內(nèi)部,如下:

public void printB(int a){
  if (a == 1) {
    int b = 2;
    System.out.println(b);
  }
}

這個(gè)也很容易做到。

6. 使用equals比較時(shí),常量盡量放在equals前,這樣不容易出現(xiàn)NullPointException

7. 返回值位數(shù)組/列表時(shí),沒有值返回值,盡量不要返回null,而是返回空數(shù)組

這樣做的好處就是,調(diào)用方法不需要先判斷是否返回nul,代碼更簡潔,而且可以減少因?yàn)槭韬龆鸬目罩羔槷惓!?/p>

8. 對流的盡量使用帶資源的try

從jdk 1.7之后出現(xiàn)了帶資源的try語句。只要實(shí)現(xiàn)了AutoCloseable接口,都可以使用帶資源的try。這樣做的好處就是,不需要再顯示的調(diào)用close方法,也就不會(huì)出現(xiàn)因?yàn)橥浾{(diào)用而引起的資源為釋放。

9. 對變量的的聲明放到循環(huán)外

10. 對字符串的操作使用StringBuilder/StringBuffer(線程安全)

例如字符串的連接,不要使用 + "" +,使用加號(hào)連接,底層使用的是StringBuilder,每使用一次加號(hào)連接賦值,都會(huì)重新new一個(gè)StringBuilder。所以建議使用直接使用StringBuilder/StringBuffer(線程安全)。

11. 常量使用大寫

12. 使用帶緩沖的輸入輸出流進(jìn)行IO操作

13. 盡量使用增強(qiáng)for遍歷

14. 不要使用魔法值

15. 盡量少用或禁用 join 關(guān)聯(lián)表,在應(yīng)用端組裝數(shù)據(jù),方便以后的分庫

16. 實(shí)現(xiàn)類和實(shí)現(xiàn)類之間慎用 extends,因?yàn)樵鰪?qiáng)了耦合性,修改父類時(shí)可能要重構(gòu)代碼。

17. Bigdecimal 比值時(shí)使用 compareTo 盡量不要使用 equals

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容