代碼規范問題


最近有做簡單的代碼規范整理,寫一下規范過程使用的工具和遇見比較多的問題。

 

一、代碼規范的重要性

  關於代碼規范的重要性網上一搜一大堆,都是很有年代的一些文章,現在寫這個好像有點太low了,簡單列一下他們(相似的文章太多,找不到原文)所說到的幾點好處:

  • 有助於團隊合作
  • 減少BUG處理
  • 降低維護成本
  • 有助於代碼審查
  • 養成規范代碼的習慣,有助於程序員自身的成長

  毋庸置疑的是隨着團隊的發展、規范化,良好的代碼規范能體現的好處會越來越明顯,提升工作效率、提高代碼質量等等...

 

二、如何保證代碼規范

   為了保證代碼的規范、質量,需要開發者自身養成良好的編碼習慣,但是很多時候每個人的風格習慣都不一樣,不利於團隊協作,即使有些公司會有人工代碼審查的環節,但是過於耗費人力資源,所以更多的是利用工具進行掃描分析。

代碼分析包括靜態分析和動態調試:

  • 靜態分析:指在不運行程序的情況下,對源代碼進行檢查分析,通過分析語法、結構、過程、接口等來檢查程序的正確性,找出代碼中存在的錯誤和缺陷。如參數不匹配、有歧義的嵌套語句、錯誤的遞歸、非法計算、可能出現的空指針引用等等。
  • 動態調試:指利用調試器跟蹤軟件的運行,尋找程序中的漏洞。

  現在主要是利用以靜態分析技術實現的相關工具對代碼進行檢查,先列一下接觸到的工具:

 工具  分析對象  備注
 Findbugs 字節碼文件  缺陷模式匹配、數據流分析。通過字節碼分析代碼存在缺陷、支持數據流分析,能查找出空指針崩潰等問題。
 CheckStyle Java源代碼  缺陷模式匹配。掃描代碼格式規范、代碼風格的工具。
 Alibaba java coding guidelines(基於PMD) Java源代碼  缺陷模式匹配、數據流分析。檢測代碼潛在錯誤。

 

 

三、工具以及事例
  • FindBugs

    FindBugs是一個開源的靜態代碼分析工具,基於LGPL開源協議,它檢查類或者JAR 文件,將字節碼與一組缺陷模式進行對比以發現可能的問題。它注重檢測真正的bug及潛在的性能問題 ,尤其注意了盡可能抑制誤檢測(false positives)的發生,不關心代碼風格格式的問題。FindBugs的檢測結果主要分一下幾種問題類型:

    • 正確性(Correctness):可能導致錯誤的代碼。比如錯誤的強制類型轉換。
    • 最佳實踐反例(Bad practice):違反了公認的最佳實踐標准。如一些流使用后沒有關閉。
    • 多線程的正確性(Multithreaded correctness):關注於同步和多線程問題。如應該使用notify()而不是notifyAll()。
    • 性能(Performance):潛在的性能問題。如:一個屬性從沒有被使用,考慮從類中去掉。
    • 危險的(Dodgy):具有潛在危險的代碼,可能運行期產生錯誤。如:對方法調用的直接引用,而方法可能返回null。
    • 惡意代碼漏洞(Malicious code vulnerability):可能受到惡意攻擊的代碼,如訪問權限修飾符的定義等。
    • 國際化(Internationalization):關於代碼國際化相關方面的。如使用平台默認的編碼格式對字符串進行大小寫轉換,這可能導致國際字符的轉換不當。

    

    簡單列幾個我們程序中FindBugs分析出現比較多的問題:

  1. May expose internal representation by returning reference to mutable object.

    可能因使引用可指向多個對象而暴露內部存儲結構。

    get/set方法直接把此對象中某一屬性的引用放到外部,可以隨便更改,違反了封裝的原則。可以在get/set方法中修改為對這類屬性(引用地址)的拷貝對象做操作。但是一般不會這么做,實際使用中bean里面的屬性設置后很少會再改動,這么做太麻煩了。

  2. Method invokes inefficient Number constructor; use static valueOf instead.

    方法調用低效數構造函數,使用靜態valueOf方法代替。

    FindBugs推薦使用Integer.ValueOf(int)代替new Integer(int),因為這樣可以提高性能。如果當你的int值介於-128~127時,Integer.ValueOf(int)的效率比Integer(int)快大約3.5倍。從源代碼可以看到,ValueOf對-128~127這256個值做了緩存(IntegerCache),如果int值的范圍是:-128~127,在ValueOf(int)時,他會直接返回IntegerCache的緩存。

  3. Boxed value is unboxed and then immediately reboxed.
    裝箱的值被拆箱,然后立即重新裝箱了。

     自動裝箱拆箱的特性,只要運算中有不同類型,當涉及到類型轉換時,編譯器就會向下轉型,再運算。

  4. Switch statement found where default case is missing.
    Switch沒有默認情況下執行的case語句。

     

  5. Inefficient use of keySet iterator instead of entrySet iterator.
    使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進行遍歷。

    當程序中有遍歷對map的key、value操作的時候,建議使用entrySet,它的性能比keySet高。通過keySet遍歷時,生成KeyIterator迭代器,如果要獲取value此時還要遍歷Map。而entrySet遍歷生成EntryIterator 迭代器,其中包含key和value。

  6. Method call passes null for non-null parameter.
    對參數為null的情況沒做處理。

     當args為空時,程序異常。

  • Checkstyle

    Checkstyle是一款檢查Java程序源代碼樣式的工具。主要的檢查項包括Javadoc注釋、命名規范、多余沒用的Imports、Size度量,如過長的方法、缺少必要的空格Whitespace、重復代碼等。它可以有效的幫助我們檢視代碼以便更好的遵循代碼編寫標准,特別適用於小組開發時彼此間的樣式規范和統一。

    按照Sun的規范太嚴格了,通常需要自定義規則,使用起來很麻煩,所以后面沒有使用Checkstyle。

  • Alibaba java coding guidelines

    Alibaba java coding guidelines是阿里巴巴2017年10月在杭州雲棲大會上發布的,把《阿里巴巴 Java 開發規約》強制條目轉化為自動插件,並實現了部分的自動編碼。項目已經在Git上開源了,地址阿里規約插件

    阿里規約插件檢查的內容參照《阿里巴巴 Java 開發規約》,基於PMD進行的代碼檢測,檢測的問題主要分為三類,對應 Snoar 中的前三個等級,前兩個級別是必須要處理的:

    • Blocker:崩潰
    • Critical:嚴重
    • Major:重要

    

 

    按照阿里規約,大量存在的問題如下,因為是中文的,而且提示信息很准確,所以修改很輕松:

    • 方法名、參數名、成員變量、局部變量都統一使用 lowerCamelCase 風格,必須遵從駝峰形式。
    • 常量命名全部大寫,單詞間用下划線隔開,力求語義表達完整清楚,不要嫌名字長。
    • 魔法值。
    • 代碼中的命名均不能以下划線或美元符號開始,也不能以下划線或美元符號結束。
    • 注釋的雙斜線與注釋內容之間有且僅有一個空格。
    • Object 的 equals 方法容易拋空指針異常,應使用常量或確定有值的對象來調用 equals。
    • 集合初始化時,指定集合初始值大小。
    • 需要進行參數校驗。
    • 類、類屬性、類方法的注釋必須使用 Javadoc 規范,使用/**內容*/格式。

 

四、總結

   其實單從這里並不能很好的做到代碼規范統一,了解到正常的應該是類似Jenkins+SonarQube+Git的方式,在提交代碼的時候會觸發檢查,不合規范的代碼不允許提交。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM