天天看點

Java開發常見錯誤整理

做過幾年的Java開發,也閱讀過一些新手寫的Java代碼,常常會發現一些Java開發人員經常犯的一些錯誤,是以将Java開發中常見錯誤整理如下:

1.NullPointException問題

這種錯誤恐怕是程式設計初期最容易犯的錯誤。 Java是面向對象的語言, 操作幾乎都是在對象之間進行的, 一個類的執行個體如果是空(null)的話則不能調用這個執行個體的方法, 否則就會出java.lang.NullPointException錯誤。 最常見的String的操作, 如:

String str = null;

if (str.equals(“Hello”)) {

System.out.println(“str is Hello”);

}

常用的避免方法就是在使用一個Object之前要判斷一下是否為null, 除非你确定它肯定是不為null的。是以應該上例修改如下:

String str = null;

if (str !=null && str.equals(“Hello”)) {

System.out.println(“str is Hello”);

}

對于String的這種equals或equalsIgnoreCase的操作常常還可以用下面的方法進行安全操作:

String str = null;

if (“Hello”.equals(str)) {

System.out.println(“str is Hello”);

}

用一個确定的不為null的String去與未知的String進行比較。

2.多餘處理語句

這種問題當然不隻是java才有的, 任何程式都有可能出現多餘的垃圾代碼, 盡管它的最終結果是正确的, 我們在寫程式的時候要盡可能避免這種不必要的處理。

常見的情況有以下幾種:

2.1多餘的執行個體構造

聲明了一個對象的執行個體, 有的人喜歡同時new一下,即給它配置設定了空間, 而在後面并沒用到配置設定的空間, 而是進行了其它的操作,例:

ArrayList resultList = new ArrayList();

try {

resultList = SomeModule.getResultList();

} catch (Exception e) {

return null;

}

resultList在聲明的時候同時給它配置設定了空間, 但在下面卻用它指向了另外傳回的位址。 雖然在寫Java程式的時候我們不用考慮記憶體的配置設定等令人頭疼的問題, Java有自己的一套記憶體管理機制, 但Java在對象的構造的時候開銷是很大的, 是以諸如此類的浪費效率的處理還是得要注意避免。

2.2循環多餘

我們經常會從一個數組或Collection中通過循環來找出一個符合條件的元素進行操作, 而在執行完之後往往會忘記跳出循環體。 例:

String[] week = new String[]{“Sun”, “Mon”, “Tue”, “Wen”, “Thu”, “Fri”, “Sat”};

for (int i = 0; i < week.length; i++) {

if (week.equals(“Tue”)) {

System.out.println(“Tue is found”);

}

}

如果上面這段程式隻是找出week中是否有Tue的話,則在找到之後應該跳出循環體, 正确的寫法如下:

for (int i = 0; i < week.length; i++) {

if (week.equals(“Tue”)) {

System.out.println(“Tue is found”);

break; (或return)

}

}

循環處理的原則就是在處理完畢的地方跳出。

2.3 重複語句

建議如果有兩個或兩個以上的地方需要用到相同的程式塊代碼, 就要考慮到使用函數, 如果一個功能塊比較獨立, 有可能在其它被調用, 這個時候也盡可能的使用方法獨立開來。

還有種情況就是在條件分支語句裡面, 各個分支都需要執行某個相同的語句, 這個時候就需要提到分支的外面去執行。

3.數組和集合的使用問題

3.1數組下标越界的問題;

  現在程式中大多都有對數組的操作,是以在調用數組的時候一定要認真檢查,看自己調用的下标是不是超出了數組的範圍,一般來說,顯示(即直接用常數當下标) 調用不太容易出這樣的錯,但隐式(即用變量表示下标)調用就經常出錯了,還有一種情況,是程式中定義的數組的長度是通過某些特定方法決定的,不是事先聲明 的,這個時候,最好先檢視一下數組的length,以免出現這個異常。

3.2 不能合理的使用集合的問題;

  不清除List、Set和Map等集合的差別,該使用Set集合的時候使用List;不知道集合的合适的使用場合的問題。

4.資源不釋放的問題

  IO操作要注意,打開記得要關閉。資料庫資源和網絡接等資源也是同樣的道理。打開的資源連接配接記得要關閉。

5.語句備援的問題

  “簡練是良好的寫作風格”,寫文章如此,寫代碼也是如此。因為簡練的代碼一般有三個好處:1.節省你的編寫時間;2.節省維護者的閱讀時間;3.提高代碼的運作效率。

 例如:params.put("status", new Integer(Status.DELETED.getValue()));

 改進:該語句應該充分使用Java的自動包裝功能。不要去new Integer 對象,因為這樣既有代碼備援,又會重複的構造對象,降低程式的運作效率。

 例如:if (isAdmin == true) {

            this.appserviceService.deleteAdminApp(id);

        }

    可以簡化為if (isAdmin) {

            this.appserviceService.deleteAdminApp(id);

        }

6.使用被廢棄的方法的問題

  一般API中廢棄的方法一定是存在着某種問題是以應該盡量避免使用。

   例如:if (date.getYear() > value.getYear()) {  ...     }

   此處Date對象的getYear()的方法被廢棄了。應該使用Calendar.get(Calendar.YEAR)去代替;

7.代碼淩亂的問題

  代碼是思路的表達,程式設計首先應該整理思路,編碼也像寫文章一樣,應該條理清晰,段落分明。按照解決問題的步驟去分段寫代碼,每段代碼的功能應該很明确。該寫成獨立方法的要使用獨立的方法去實作。

8.不能充分使用Java5的新特性的問題

  應該充分的使用Java5的Autoboxing/Unboxing功能,Generics(泛型),Varargs(可變參數)等功能來編寫代碼,進而使用代碼更加簡潔和健壯。

9.對常用的API不熟悉的問題

  “Don't Reinvent the Wheel”--不要重複發明輪子,要熟悉jdk和apache常用包的API,沒有充足的理由就不要去寫别人已經寫過的方法。“君子善假于物也”,熟悉常用的API,熟練的去使用它們吧!

10.不必要的類型轉化的問題

   也許是對字元串類型過于熱愛的緣故吧,經常發現有些代碼原本可以使用Integer或者Date類型去做的事情,有些工程師卻熱衷于将其轉化為字元串類型,需要知道類型轉化是需要付出額外的時間成本的。這樣的代碼既啰嗦又影響代碼的效率。

11.代碼注釋的問題

   注釋代碼時,要考慮到不僅将來維護你代碼的開發人員要看,而且你自己也可能要看。用Phil Haack大師的話來說就是:“一旦一行代碼顯示螢幕上,你也就成了這段代碼的維護者”。是以,對于我們寫得好(差)的注釋而言,我們将是第一個受益者(受害者)。

   注釋的黃金規則:易讀的代碼,人性化的去書寫代碼。這個很重要。寫代碼要對自己負責,對維護者負責。

   對每個方法都要說明:功能、每個參數的意義,參數可以取哪些值,傳回值有哪些,在什麼情況下傳回什麼值。對每個源檔案都要在開頭以注釋的方式說明它的作用。

   還有的注釋是無用,這樣的注釋也不應該出現,不要侮辱閱讀代碼者的智商如: 

    if (a == 5)      // if a equals 5

    counter = 0; // set the counter to zero

   這樣顯而易見的注釋就不需要寫了,寫這些無用的注釋隻會會浪費你的時間,并将轉移讀者對該代碼細節的了解。

12.代碼格式的問題

   盡量遵照規範去格式化代碼,該換行的換行,該空格的空格,該縮進需要縮進,以提高代碼的可讀性。

13.命名規範的問題

 命名規範使程式更易讀,進而更易于了解。它們也可以提供一些有關辨別符功能的資訊,以助于了解代碼,例如,不論它是一個常量,包,還是類。Java語言中包、類、方法、變量和常量都有其命名規範。在Java語言命名規範網上有很多很好的文章,這裡就不再贅述。

以上是本人整理的Java開發中的常見問題(其中有些問題也适用其它開發語言),歡迎大家參與讨論,提出自己的看法,或者發表自己的見解。