如何使用插件幫你規範代碼
前言
阿里巴巴將《阿里巴巴Java開發手冊》文檔進行了升級,在2017年10月14日杭州雲棲大會,Java代碼規約掃描插件全球首發儀式正式啓動,規範正式以插件形式公開走向業界,引領Java語言的規範之路。使用該插件進行掃描工程,可以掃描出Blocker/Critical/Major三個等級的隱患代碼,在Snoar中對代碼規則有五個級別,這是前三個,翻譯下就是:崩潰/嚴重/重要,也就是說前兩級別是必須要處理掉的。同時還會給出修改意見。可以說不但規範了代碼,也帶你避免掉了一些潛在的bug。
一、IDEA如何安裝阿里巴巴代碼規範插件
-
啓動IDEA >> File >> Settings >> Plugins ,搜索 Alibaba Java Code Guidelines(阿里巴巴Java代碼指南)插件,點擊Install進行安裝。
-
安裝好重啓IDEA,之後生效。需要注意的是 插件基於JDK1.7打包 ,如果IDEA啓動時使用的是JDK1.6版本的話就會報Unsupported.major.minor version 51.0異常,所以建議大家升級一下。
-
IDEA重啓之後點擊工程右鍵,或者使用默認快捷鍵Ctrl+Shift+Alt+J來掃描你的工程吧。看看你的代碼有多少不規範的地方呢。
-
也可以點擊具體的某個類右鍵進行掃描。
-
掃描整個工程,將不符合規約的代碼按 Blocker、Critical、Major 三個等級顯示,右側窗口還有針對代碼的批量修復功能。
-
實時檢測功能,在開發時,對當前文件實時進行檢測,並高亮顯示出來,同時也給出修改提示。可以說是非常好用了。
-
關閉實時檢測功能
如果你正在閱讀一些代碼,恰巧代碼又沒有按照阿里代碼規範寫,此時屏幕上都是一些紅色、黃色的警告,嚴重影響閱讀。這個時候可以右擊工程點擊關閉實時檢測的功能。
8. 或許阿里條約有些並不適合自己團隊的開發要求,這也不需要擔心,因爲也可以單獨的關閉某條規則。或者是修改其提示的級別。是不是很人性化呀。
File>>Settings >>Editor >> Inspections
二、修改不規範代碼
掃描完整個工程之後發現有很多不符合規範的代碼,小編就挑一些跟大家一起修改吧。
1.不允許出現任何魔法值(即未經定義的常量)直接出現在代碼中。所謂的魔法值就是,未經定義的常量字面量,所有在代碼中使用的常量必須預先經過定義。
反例:
if (key.equals("zhangSan")) {
//...
}
建議改爲:
String KEY_PRE = "zhangSan";
if(KEY_PRE.equals(key)){
//...
}
2.Object的equals方法容易拋空指針異常,應使用常量或確定有值的對象來調用equals。(是不是有的小夥伴沒有注意過這個問題?)
反例:
public void f(String str) {
String inner = "hi";
if (str.equals(inner)) {
System.out.println("hello world");
}
}
建議改爲:
public void f(String str) {
String inner = "hi";
if (inner.equals(str)) {
System.out.println("hello world");
}
}
3.所有的覆寫方法,必須加@Override註解。
其實Override註解的本身並沒有什麼作用,但是它可以告訴代碼的讀者,這個是覆蓋父類的方法。如果方法名、參數、異常定義錯誤,導致不能正確覆蓋父類的方法,編譯器會提示錯誤。比如getObject()與get0bject()的問題。一個是字母的O,一個是數字的0,加@Override可以準確判斷是否覆蓋成功。所以在意細節還是很重要的。
4.事務場景中,拋出異常被catch後,如果需要回滾,一定要手動回滾事務。
反例 (註解【Transactional】需要設置rollbackFor屬性。):
@Service
@Transactional
public class MechanicalInformationService {
}
建議改爲:
例子一:
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
}
}
例子二:
@Service
public class UserServiceImpl implements UserService {
@Override
@Transactional(rollbackFor = Exception.class)
public void save(User user) {
}
}
例子三:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private DataSourceTransactionManager transactionManager;
@Override
@Transactional
public void save(User user) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
} catch (Exception ex) {
transactionManager.rollback(status);
throw ex;
}
}
}
5.循環體內,字符串的連接方式,使用StringBuilder的append方法進行擴展。
說明:反編譯出的字節碼文件顯示每次循環都會new出一個StringBuilder對象,然後進行append操作,最後通過toString方法返回String對象,造成內存資源浪費。(這一點是需要十分注意的,看完之後不要再用+連接字符串了哦)
反例:
String result;
for(String string:tagNameList){
result=result+string;
}
建議改爲:
StringBuilder stringBuilder = new StringBuilder();
for(String string:tagNameList){
stringBuilder.append(string);
}
String result=stringBuilder.toString();
6.除常用方法(如getXxx/isXxx)等外,不要在條件判斷中執行復雜的語句,將複雜邏輯判斷的結果賦值給一個有意義的布爾變量,以提高可讀性。
反例:
if((file.open(fileName,"w")!=null)&&(...)||(...)){
// ...
}
建議改爲:
boolean existed=(file.open(fileName,"w")!=null)&&(...)||(...);
if(existed){
//...
}
- 集合初始化時,指定集合初始值大小。
說明:HashMap使用如下構造方法進行初始化,如果暫時無法確定集合大小,那麼指定默認值(16)即可。
反例:
Map<String, String> map = new HashMap<String, String>();
建議改爲:
Map<String, String> map = new HashMap<String, String>(16);
三、結尾
大家可以將《阿里巴巴Java開發手冊》下下來認真閱讀。這都是阿里技術精英經過實戰不斷完善的經驗總結,可以很好的幫我們規範Java編碼,提高Java開發質量和效率、同時大大降低了代碼的維護成本。讓程序員碼出更優質的代碼。將不符合規範的代碼修改,逐步養成良好的編碼習慣!