java開發編碼規範

  1. 方法的返回類型, 方法參數, 變量聲明時均採用接口類型, 而不是實際類型:
/** 定義接口變量爲接受類型的好處: 1).面向接口編程 一種規範約束 制定者(或者叫協調者),實現者(或者叫生產者),調用者(或者叫消費者)。 接口本質上就是由制定者來協調實現者和調用者之間的關係。 只有實現者和調用者都遵循「面向接口編程」這個準則,制定者的協調目的才能達到。 接口的語義是can-do語義,表約束(Constraint)像JDBC的規範API,無論你使用哪一套實現,咱們使用的時候都是使用相同的API. 分離設計與實現 使得系統能夠支持開閉原則和依賴倒轉原則。設計師能夠設計出接口,而程序員能夠依照接口去寫實現。 2).解耦合 在必定程度上解耦合,依賴接口還不依賴具體實現,在替換實現類的時候,能夠將影響減到最小. 3).在依賴接口的狀況下,單元測試更容易,使用mock也更容易,在TDD中,測試驅動就是要讓程序易於測試。 4).與設計有關 在一個面向對象的系統中,系統的各類功能是由許許多多的不一樣對象協做完成的。 在這種狀況下,各個對象內部是如何實現本身的對系統設計人員來說就不那麼重要了; 而各個對象之間的協做關係則成爲系統設計的關鍵。 在OSGI規範中,接口與實現的分離是用得最淋漓盡致的。 5).參考spring中的IOC的實現 */ public Map<String, Object> getStockWarrantIV(String ul, String updateDate) { //HashMap<String, Object> ivMap = new HashMap<>(); Map<String, Object> ivMap = new HashMap<>(); try { String key = STOCK_WARRANT_IV_PREFIX + ul; String hashKey = updateDate; ivMap = (HashMap<String, Object>) redisTemplate.boundHashOps(key).get(hashKey); } catch (Exception e) { LOG.error("getStockWarrantIV", e); } return ivMap; } 
  1. 代碼中不要有多餘的空行, 無效的註釋,無心義的註釋要刪掉; 註釋要規範, 符合javadoc原則;註釋和日誌細節寫清楚,不要出錯誤;變量命名規範,不要存在歧義和衝突;java

  2. 方法命名符號常規英語表達習慣, 能從名字明白方法的做用;程序員

  3. 調用工具類, 儘可能調用已經封裝好的工具類方法,減小自定義工具類方法編碼;redis

  4. 判斷字符串非空, 調用StringUtils類中方法, 注意isBlank和isEmpty的區別spring

1.StringUtils裏的isEmpty方法和isBlank方法的區別 isEmpty() public static boolean isEmpty(String str) { return str == null || str.length() == 0; } isBlank() public static boolean isBlank(String str) { int strLen; if (str != null && (strLen = str.length()) != 0) { for(int i = 0; i < strLen; ++i) { // 判斷字符是否爲空格、製表符、tab if (!Character.isWhitespace(str.charAt(i))) { return false; } } return true; } else { return true; } } 結論 1).isEmpty 沒有忽略空格參數,是以是否爲空和是否存在爲判斷依據 2).isBlank 是在 isEmpty 的基礎上進行了爲空(字符串都爲空格、製表符、tab 的狀況)的判斷。(通常更爲經常使用) StringUtils.isEmpty("yyy") = false StringUtils.isEmpty("") = true StringUtils.isEmpty(" ") = false StringUtils.isBlank("yyy") = false StringUtils.isBlank("") = true StringUtils.isBlank(" ") = true 

6.處理時間用joda庫中的函數和java8中的時間函數,保證線程安全,避免使用Calendar以及jdk8之前的方法;數據庫

7.判斷集合非空, CollectionUtils.isNotEmpty; 判斷Map非空, MapUtils.isNotEmpty; 儘可能少用原始方法判斷, 能用工具包儘可能用工具包;編程

8.集合排序, 天然逆序用Comparator.reverseOrder(), 不要用重寫compare方法實現;緩存

9.new的對象不能能爲null, 不作爲null的判斷, 而且不作無效的new操做, 有賦值就不new;安全

10.在設計到時間的格式轉換時注意時區的影響, 以下:併發

//用format會致使時區的錯誤 hkStockRedisDao.setCallOrPullIVsRegion(ul, String.format("%tF", time.toDate()), ivMaps); //考慮時區的影響, 尤爲是在設計到不一樣交易所的狀況 hkStockRedisDao.setCallOrPullIVsRegion(ul, TimeUtils.printHkDate(time.getMillis()), ivMaps); public static final DateTimeZone TIMEZONE_HK = DateTimeZone.forID("Asia/Hong_Kong"); private static final DateTimeFormatter COMMON_DATE_FORMAT_HK = DateTimeFormat.forPattern("yyyy-MM-dd") .withZone(TIMEZONE_HK); public static String printHkDate(long timestamp) { return COMMON_DATE_FORMAT_HK.print(timestamp); } 

11.在作條件判斷時考慮周全,無效無心義的判斷要減小,沒有必要的else儘可能減小, return語句在if, else裏儘可能減小, 在外面return;maven

12.在作時間的比較計算時, 用joda庫或者java8中的日期操做方法: 好比判斷時間相差三個月, 用DateTime中的minusMonths函數,考慮11月和2月之間的差

int timeDiff = expireDateTime.minusMonths(3).compareTo(currentDate); 
  1. 無效的import要及時去掉, StringUtils用lang3的;

  2. 操做數據庫時須要考慮到性能因素, 不能只認結果;

  3. 異常處理, 強轉須要捕獲異常;

try 塊:用於捕獲異常。其後可接零個或多個catch塊,若是沒有catch塊,則必須跟一個finally塊。 catch 塊:用於處理try捕獲到的異常。 finally 塊:不管是否捕獲或處理異常,finally塊裏的語句都會被執行。當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回以前被執行。在如下4種特殊狀況下,finally塊不會被執行: 1)在finally語句塊中發生了異常。 2)在前面的代碼中用了System.exit()退出程序。 3)程序所在的線程死亡。 4)關閉CPU
  1. 類型相同的變量直接賦值, 無需在從新new

  2. 出現太多常量, 須要提取公共常量;

  3. 分頁時主要默認最小頁大小和最大頁大小, 避免返回所有;

  4. 常量命名規範, 大寫下劃線;

  5. 方法權限, 類中調用private, 子類調用protected;

  6. 代碼格式調整option+command+l, "{"前有空格, 語句對齊, 用option+command+l快捷鍵對齊;

  7. 若是用//註釋, 須要與註釋內容之間有一個空格;

  8. 相同業務類型, 相贊成義用才用可變參數, 可變參數放在最後一個參數;

  9. 包裝類型的值比較用equals方法, 不用==, 由於java在包裝類型有緩存;

  10. 構造方法裏不加任何業務邏輯, 放在init方法裏;

  11. 只要重寫equals就必須重寫hashCode

  12. 關於通配符: 泛型通配符<? extends T>來接收返回的數據,此寫法的泛型集合不能使用add方 法,而<? super T>不能使用get方法,作爲接口調用賦值時易出錯;PECS(Producer Extends Consumer Super)原則:第1、頻繁往外讀取內 容的,適合用<? extends T>。第2、常常往裏插入的,適合用<? super T>;

  13. 不要在 foreach 循環裏進行元素的 remove/add 操做。remove 元素請使用 Iterator 方式,若是併發操做,須要對 Iterator 對象加鎖。

  14. 集合初始化時,指定集合初始值大小

  15. 使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進行遍歷; keySet 實際上是遍歷了 2 次,一次是轉爲 Iterator 對象,另外一次是從 hashMap 中取出 key 所對應的 value。而 entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中,效 率更高。若是是 JDK8,使用 Map.foreach 方法。

  16. 線程池不容許使用 Executors 去建立,而是經過 ThreadPoolExecutor 的方式,這樣 的處理方式讓寫的同窗更加明確線程池的運行規則,規避資源耗盡的風險。

  17. SimpleDateFormat 是線程不安全的類,通常不要定義爲static變量,若是定義爲 static,必須加鎖,或者使用 DateUtils 工具類。

注意線程安全,使用 DateUtils。亦推薦以下處理: private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; 若是是 JDK8 的應用,可使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 SimpleDateFormat,官方給出的解釋:simple beautiful strong immutable thread-safe
  1. public方法傳參注意, 防止調用者調錯

  2. if else 考慮清楚, 須要讓看的人以爲邏輯清晰

  3. 分頁實現, 須要totalPage, pageSize, page三個參數, totalPage和page須要返回給客戶端

  4. maven在打包發佈前要clean下, 防止本地的target下的classess影響發佈後的結果

  5. 字符串截圖判斷是否越界 stockStat.getNameCN().substring(2, 4);

比較: redisTemplate.boundValueOps(key).get() redisTemplate.opsForValue().get(key);

相關文章
相關標籤/搜索