安裝步驟見 https://www.cnblogs.com/bestzhang/p/util.html
解釋下Blocker/Critical/Major三個等級,
在 Snoar 中對代碼規則有五個級別,這是前三個:崩潰/嚴重/重要 ,也就是說前兩級別是必須要處理掉的。
Blocker:
long或者Long初始賦值時,必須使用大寫的L,不能是小寫的l,小寫容易跟數字1混淆,造成誤解。
在if/else/for/while/do語句中必須使用大括號,即使只有一行代碼,避免使用下面的形式:if (condition) statements;
在使用正則表達式時,利用好其預編譯功能,可以有效加快正則匹配速度。 說明:不要在方法體內定義:Pattern pattern = Pattern.compile(規則);
public class XxxClass {
// Use precompile
private static Pattern NUMBER_PATTERN = Pattern.compile("[0-9]+");
public Pattern getNumberPattern() {
// Avoid use Pattern.compile in method body.
Pattern localPattern = Pattern.compile("[0-9]+");
return localPattern;
}
}
所有的覆寫方法,必須加@Override註解。 反例:getObject()與get0bject()的問題。一個是字母的O,一個是數字的0,加@Override可以準確判斷是否覆蓋成功。另外,如果在抽象類中對方法簽名進行修改,其實現類會馬上編譯報錯。
獲取當前毫秒數:System.currentTimeMillis(); 而不是new Date().getTime(); 說明:如果想獲取更加精確的納秒級時間值,用System.nanoTime。在JDK8中,針對統計時間等場景,推薦使用Instant類。
public class TimeMillisDemo {
public static void main(String args[]) {
// Positive example:
long a = System.currentTimeMillis();
// Negative example:
long b = new Date().getTime();
System.out.println(a);
System.out.println(b);
}
}
Critical
Object的equals方法容易拋空指針異常,應使用常量或確定有值的對象來調用equals。
public void f(String str){
String inner = "hi";
if (inner.equals(str)) {
System.out.println("hello world");
}
}
對於Service和DAO類,基於SOA的理念,暴露出來的服務一定是接口,內部的實現類用Impl的後綴與接口區別
public interface DemoService{
void f();
}
public class DemoServiceImpl implements DemoService {
@Override
public void f(){
System.out.println("hello world");
}
}
常量命名應該全部大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長
public class ConstantNameDemo {
/**
* max stock count
*/
public static final Long MAX_STOCK_COUNT = 50000L;
所有的枚舉類型字段必須要有註釋,說明每個數據項的用途。
public enum TestEnum {
/**
* agree
*/
agree("agree"),
/**
* reject
*/
reject("reject");
private String action;
TestEnum(String action) {
this.action = action;
}
public String getAction() {
return action;
}
}
方法名、參數名、成員變量、局部變量都統一使用lowerCamelCase,必須遵從駝峯形式
Major
不允許任何魔法值(即未經定義的常量)直接出現在代碼中。
Negative example:
//Magic values, except for predefined, are forbidden in coding.
if (key.equals("Id#taobao_1")) {
//...
}
Positive example:
String KEY_PRE = "Id#taobao_1";
if (KEY_PRE.equals(key)) {
//...
}
中括號是數組類型的一部分,數組定義如下:String[] args
String[] a = new String[3];
包名統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。包名統一使用單數形式,但是類名如果有複數含義,類名可以使用複數形式
com.alibaba.mpp.util / com.taobao.tddl.domain.dto
單個方法的總行數不超過80行。 說明:除註釋之外的方法簽名、結束右大括號、方法內代碼、空行、回車及任何不可見字符的總行數不超過80行。
及時清理不再使用的代碼段或配置信息。 說明:對於垃圾代碼或過時配置,堅決清理乾淨,避免程序過度臃腫,代碼冗餘。
循環體內,字符串的聯接方式,使用StringBuilder的append方法進行擴展。 說明:反編譯出的字節碼文件顯示每次循環都會new出一個StringBuilder對象,然後進行append操作,最後通過toString方法返回String對象,造成內存資源浪費。
Negative example:
String result;
for (String string : tagNameList) {
result = result + string;
}
Positive example:
StringBuilder stringBuilder = new StringBuilder();
for (String string : tagNameList) {
stringBuilder.append(string);
}
String result = stringBuilder.toString();
所有的抽象方法(包括接口中的方法)必須要用javadoc註釋、除了返回值、參數、異常說明外,還必須指出該方法做什麼事情,實現什麼功能。 說明:如有實現和調用注意事項,請一併說明。
/**
* fetch data by rule id
*
* @param ruleId rule id
* @param page page number
* @param jsonContext json format context
* @return Result<XxxxDO>
*/
Result<XxxxDO> fetchDataByRuleId(Long ruleId, Integer page, String jsonContext);
所有的類都必須添加創建者信息。 說明:在設置模板時,注意IDEA的@author爲${USER},而eclipse的@author爲${user},大小寫有區別,而日期的設置統一爲yyyy/MM/dd的格式。
/**
* Demo class
*
* @author keriezhang
* @date 2016/10/31
*/
public class CodeNoteDemo {
}
方法內部單行註釋,在被註釋語句上方另起一行,使用//註釋。方法內部多行註釋使用/* */註釋。注意與代碼對齊。
public void method() {
// Put single line comment above code. (Note: align '//' comment with code)
int a = 3;
/**
* Some description about follow code. (Note: align '/**' comment with code)
*/
int b = 4;
}
類、類屬性、類方法的註釋必須使用javadoc規範,使用/**內容*/格式,不得使用//xxx方式和/*xxx*/方式。 說明:在IDE編輯窗口中,javadoc方式會提示相關注釋,生成javadoc可以正確輸出相應註釋;在IDE中,工程調用方法時,不進入方法即可懸浮提示方法、參數、返回值的意義,提高閱讀效率。
/**
*
* XXX class function description.
*
*/
public class XxClass implements Serializable {
private static final long serialVersionUID = 113323427779853001L;
/**
* id
*/
private Long id;
/**
* title
*/
private String title;
/**
* find by id
*
* @param ruleId rule id
* @param page start from 1
* @return Result<Xxxx>
*/
public Result<Xxxx> funcA(Long ruleId, Integer page) {
return null;
}
}
類名使用UpperCamelCase風格,必須遵從駝峯形式,但以下情形例外:(領域模型的相關命名)DO / BO / DTO / VO / DAO
返回類型爲基本數據類型,return包裝數據類型的對象時,自動拆箱有可能產生NPE
public int method() {
Integer a = null;
return a;
}
避免採用取反邏輯運算符。 說明: 取反邏輯不利於快速理解,並且取反邏輯寫法必然存在對應的正向邏輯寫法。
Negative example:
// Use `if (!(x >= 628))` to represent that x is less than 628.
if (!(x >= 628)) {
// ...
}
Positive example:
// Use `if (x < 628)` to represent that x is less than 628.
if (x < 628)) {
// ...
}
除常用方法(如getXxx/isXxx)等外,不要在條件判斷中執行復雜的語句,將複雜邏輯判斷的結果賦值給一個有意義的布爾變量,以提高可讀性。 說明:很多if語句內的邏輯相當複雜,閱讀者需要分析條件表達式的最終結果,才能明確什麼樣的條件執行什麼樣的語句,那麼,如果閱讀者分析邏輯表達式錯誤呢?
Negative example:
if ((file.open(fileName, "w") != null) && (...) || (...)) {
// ...
}
Positive example:
boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
//...
}
集合初始化時,指定集合初始值大小。 說明:HashMap使用如下構造方法進行初始化,如果暫時無法確定集合大小,那麼指定默認值(16)即可。
Negative example:
Map<String, String> map = new HashMap<String, String>();
Positive example:
Map<String, String> map = new HashMap<String, String>(16);