<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 開發(fā)的編程噩夢,這些坑你沒踩過算我輸

          共 3858字,需瀏覽 8分鐘

           ·

          2020-08-08 10:13

          歡迎點擊?“未讀代碼” ,關注公眾號,文章每周更新

          2020年8月2日?上海張江

          很多 Java 初學者在開始編程時會出現(xiàn)一些問題,這些問題并不是指某個特定領域的問題,也不是指對某個業(yè)務不熟悉而導致的問題,而是對基礎知識不夠熟悉導致的問題。而就是這些問題讓我們編寫了一些不夠健壯的代碼。這篇文章會列舉幾種編程初學者常常出現(xiàn)的一些問題,我相信這些問題多多少少也曾困擾著現(xiàn)在或曾經(jīng)的你。如果覺得文章不錯,不妨點贊分享,讓更多人跳過這些開發(fā)中的坑。

          隨處可見的 Null 值

          我見過很多的代碼會把 Null 值作為返回值,當你預期是一個字符串時,意外得到了一個 Null 值;當你預期得到一個 List 時,意外又得到了一個 Null 值,如果你不進行處理,那么你還會意外得到 NullPointerException. 就像下面這樣。

          // 情況1String userTag = getUserTag();if (userTag.equals("admin")) { // NullPointerException   // ...}
          // 情況2List carList = getCarList();for (String car : carList) { // NullPointerException // ...}

          為了防止這種情況,你可以在 List 返回時給出一個空的集合而不是 Null,如果是字符串,你可以把要確定有值對象放在比較的前面。

          if ("admin".equals(userTag)) {    // ...}// 或者if (Objects.equals(userTag,"admin")){    // ...}

          沒有進行空值檢查

          可能你考慮到了上面的 Null 值情況,但是在實際處理時沒有考慮空值情況,比如字符空串空串 "",或者集合為空。那么在后續(xù)處理時又有可能得到一個 NullPointerException. 所以你應該進行空值判斷。

          String userTag = getUserTag();if (userTag != null && userTag.trim() != "") {    // ...}
          List carList = getCarList();if (carList != null && !carList.isEmpty()) { // ...}

          忽略的異常處理

          異常處理總是一件煩人的事,而忽略異常似乎總有一種吸引人的魔力。我見過像下面這樣的代碼。

          try {    List result= request();    // ...}catch (Exception e){    }

          你沒有看錯,catch 中沒有任何內(nèi)容,后來出現(xiàn)了問題,看著日志文件一片太平無跡可尋。異常是故意拋出來的,你應該正確處理它們或者繼續(xù)拋出。而且同時,你該輸出一行日志用來記錄這個異常,方便以后的問題追蹤。

          沒有釋放資源

          在讀取文件或者請求網(wǎng)絡資源時,總是需要進行 close 操作,這很重要,否則可能會阻塞其他線程的使用。但是初學者可能會忘記這一步操作。其實在 Java 7 開始,就提供了 try-with-resources 自動關閉資源的特性,只需要把打開的資源放入 try 中。

          try (FileReader fileReader = new FileReader("setting.xml")) {    // fileReader.read();    // ...} catch (Exception e) {    e.printStackTrace();}

          像上面這樣,不需要在 finally 里手動調(diào)用 fileReaderclose 方法關閉資源,因為放在 try 里的資源調(diào)用會在使用完畢時自動調(diào)用 close. 而且不管是否有異常拋出,這很實用。

          ConcuretModificationException

          總有一天你會遇到 ConcuretModificationException ,然后開始百度搜索它的解決方式,這個異常最常見的場景是你在遍歷一個集合時進行更新操作,比如像下面這樣。

          List list = new ArrayList<>();list.add("a1");list.add("b1");list.add("b2");list.add("c1");for (String s : list) {    if ("b1".equals(s)) {        list.remove(s);    }}

          這個異常很有用處,因為 ArrayList 不是線程安全的集合,假設你這邊一邊遍歷,另一個線程不斷更新,非線程安全集合會導致你的遍歷結果不正確,所以這個異常的存在是合理的。同理 HashMap 也是如此,關于 HashMap 之前已經(jīng)有一篇文章詳細介紹了,可以參考 最通俗易懂的 HashMap 源碼分析解讀。

          缺少注釋

          準確的注釋可以救人于水火,這點有時候一點也不夸張。雖然說優(yōu)秀的代碼本身就是非常好的注釋,但是這實際開發(fā)起來,很少發(fā)生。注釋并不需要你事無巨細的一一記錄,但是你該在核心邏輯添加應有的注釋,比如復雜邏輯的實現(xiàn)思路,當前邏輯業(yè)務需求。某個判斷的添加原因,某個異常的發(fā)生情況等等。這可以讓你在未來的某一天需要回看現(xiàn)在的代碼時感謝自己。更可以讓你在某天的甩鍋中輕松勝出。

          不進行代碼測試

          我見過有些同事在功能開發(fā)完畢后直接扔給對接同事使用,而自己卻沒有經(jīng)過任何測試,或者只是測試了某個簡單的情況。測試是開發(fā)過程中的重要環(huán)節(jié),沒有經(jīng)過嚴格測試的代碼很難說沒有問題,我覺得在功能開發(fā)完畢后至少需要單元測試,特殊用例測試,集成測試以及其他形式的測試。嚴格的測試不僅可以第一時間發(fā)現(xiàn)問題,更可以減少后面不必要的對接調(diào)試時間

          重復造輪子

          你知道的,Java 社區(qū)非常活躍,存在著大量的第三方類庫,開源作者可能花費了數(shù)年時間去維護和完善類庫,這些類庫非常優(yōu)秀。同時 JDK 也提供了大量的常用的功能封裝。這些都可以為我們的開發(fā)速度插上翅膀。所以,當你需要一個功能時候,應該首先看下 JDK 和已經(jīng)引入的類庫中是否已經(jīng)存在相同功能,而不是自己重復造輪子,而且大部分情況下你造的輪子還不如別人好。

          下面舉些例子。

          • 你需要日志記錄,可以使用 logback.
          • 你需要網(wǎng)絡操作,可以使用 netty.
          • 你需要解析 JSON,可以使用 gson.
          • 你需要解析表格,可以使用 apache poi.
          • 你需要通用操作,可以使用 apache commons.

          另外一種情況是,你可能不知道某個功能在 JDK 中已經(jīng)實現(xiàn),這時候你應該多多查看 JDK Document. 我就在工作中見到過同事手寫字符串 split,為了獲取時間戳把 Date 對象轉(zhuǎn)換到 Calendar.

          缺少必要的溝通

          這個部分是和開發(fā)沒有關系的,但是這個環(huán)節(jié)往往會影響最終的開發(fā)結果。進行具體的開發(fā)之前,你應該詳細的溝通并理解功能的需求,這樣你才能針對具體的需求寫出不偏離實際需要的代碼。有時候你很有可能因為缺少必要的溝通,錯誤了理解了需求,最終在開發(fā)完畢后發(fā)現(xiàn)自己寫的功能完全沒有用處。

          沒有代碼規(guī)范

          代碼規(guī)范性非常重要,如果一個項目里充斥著各種稀奇古怪的代碼規(guī)范,會讓維護者十分頭疼。而且軟件行業(yè)高速發(fā)展,對開發(fā)者的綜合素質(zhì)要求也越來越高,優(yōu)秀的編程習慣也可以提高軟件的最終質(zhì)量。比如:標新立異的命名風格挑戰(zhàn)閱讀習慣;五花八門的錯誤碼人為地 增加排查問題的難度;工程結構混 亂導致后續(xù)項目維護艱難;沒有鑒權的漏洞代碼易被黑客攻擊;質(zhì)量低下的代碼上線之后漏洞百出等等。因為沒有統(tǒng)一的代碼規(guī)范,開發(fā)中的問題可能層出不窮。

          下面簡單列舉些應該統(tǒng)一的開發(fā)規(guī)范。如命名風格如何是好;常量名稱結構怎樣;代碼格式怎么統(tǒng)一;日期時間格式如何處理;集合處理注意事項;日志打印有無規(guī)范;前后交互具體規(guī)約等。

          上面所說的開發(fā)規(guī)范代碼規(guī)范推薦阿里推出的 《Java 開發(fā)手冊》,里面詳細列舉了在 Java 開發(fā)中各個方面應該遵守的規(guī)約和規(guī)范。最新版本在 8月 3日已經(jīng)發(fā)布,可以在公眾號 “未讀代碼” 直接回復?"java"?獲取最新版 pdf.

          總結

          Bug 和技術上的誤解都是美麗的謎團,福爾摩斯般的我們終將解決這些問題。命運自己掌握,每一次探清的這些技術誤解,都會增加我們對開發(fā)編碼的理解。盡情接招吧,色彩斑斕才有趣,萬般體驗才是人生,不管是多樣的技術,還是多樣的問題,我都想看見。

          參考:

          [1]?A beginner’s guide to Java programming nightmares

          [2]?Java? Platform, Standard Edition 8 API Specification

          最后的話
          文章有幫助可以點個「在看」或「分享」,都是支持,我都喜歡!
          文章每周持續(xù)更新,要實時關注我更新的文章以及分享的干貨,可以關注「?未讀代碼?」公眾號。
          ----- END -----

          "未讀代碼,一線技術工具人的學習、生活與見聞"

          一個「在看」,一段時光?

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人大骚逼网 | 黄色日本免费 | 国产精品内射婷婷 | 大香蕉精品在线 | AV日韩成人 |