Java 開發(fā)規(guī)范(Android)

Java開發(fā)規(guī)范

1.命名風(fēng)格

  1. 參數(shù)名,變量名以小駝峰lowerCamelCase規(guī)范:profileName
  2. 類名以大駝峰UpperCamelCase規(guī)范:UserDO
  3. 常量名大寫,單詞下劃線隔開MAX_STOCK_COUNT
  4. 使用英文命名,不能出現(xiàn)拼音,以最為準(zhǔn)確的翻譯為準(zhǔn).
  5. 抽象類使用Abstract或者Base開頭,異常類使用Exception結(jié)束
  6. 數(shù)組使用類型[] 變量名方式:String[] names,而不是String args[]
  7. 包名使用小寫,不加下劃線.
  8. 除了通用縮寫方式,盡量使用完整單詞組合命名.通用縮寫見下表.
  9. 不能出現(xiàn)int a這樣的"未知"變量名,必須使用一個(gè)可以表達(dá)含義的單詞或短語(yǔ).
  10. 接口中的方法和變量不加修飾符(方法默認(rèn)public abstract,變量默認(rèn)public static final)
  11. 當(dāng)使用設(shè)計(jì)模式時(shí),推薦類名使用設(shè)計(jì)模式名OrderFactory,LoginProxy,DataObserver
  12. 業(yè)務(wù)類接口以I開頭IPresenter,實(shí)現(xiàn)以ImplLoginPresenterImpl結(jié)尾.
  13. 枚舉類以Enum結(jié)尾.枚舉成員大寫加下劃線分隔.
  14. 方法命名規(guī)范:
    (1). 獲取單個(gè)對(duì)象以get做前綴
    (2). 獲取多個(gè)對(duì)象以list做前綴,復(fù)數(shù)形式結(jié)尾: listBooks
    (3). 獲取統(tǒng)計(jì)值用count做前綴
    (4). 插入方法以save/insert做前綴
    (5). 刪除方法以remove/delete做前綴
    (6). 修改方法以u(píng)pdate做前綴
  15. 領(lǐng)域?qū)ο竺?guī)范:
    (1). 數(shù)據(jù)庫(kù)對(duì)象xxxDO
    (2). 頁(yè)面展示對(duì)象xxxVO
    (3). 上傳接口對(duì)象xxxReq
    (4). 接口獲取對(duì)象xxxRes
    (5). 業(yè)務(wù)對(duì)象xxxBO

2.常量定義

  1. 在long或Long類型賦值時(shí),數(shù)值使用大寫L,而不是小寫l,小寫l容易和1混淆
  2. 常量類需要按功能分類,不能使用大而全的常量類.例:緩存使用CacheConsts,配置使用ConfigConsts
  3. 如果變量值僅在較小規(guī)模的固定范圍內(nèi)變化,使用enum,如季節(jié),星期,生命周期,業(yè)務(wù)狀態(tài)等.

3.代碼格式

  1. 文件編碼使用UTF-8,IDEA設(shè)置:
    (1). Preference->Editor->Code Style-> File Encodings "Global Encoding","Project Encoding","Default encoding for properties files"都設(shè)置為"UTF-8"UTF-8"
    (2). "Create UTF-8 files"設(shè)置為"with No BOM"
  2. 空格使用Unix格式,IDEA設(shè)置:
    Preference->Editor->Code Style-> Line separator設(shè)置為"Unix and OS X (\n)
  3. 必須使用4個(gè)空格縮進(jìn),不能使用Tab,IDEA設(shè)置:
    Preference->Editor->Code Style->Java -> Tabs and Indents -> "Tab size"和"Indent"設(shè)置為4,勿勾選"Use tab character"
  4. 每行超出120個(gè)字符換行,換行規(guī)則:
    (1). 換行縮進(jìn)4個(gè)空格,再換行不再縮進(jìn)
    (2). 運(yùn)算符和下文一起換行
    (3). 方法調(diào)用的.與方法一起換行
    (4). 方法內(nèi)多參數(shù)需換行時(shí),在逗號(hào)后換行
    IDEA設(shè)置:
    (1). Preference->Editor->Code Style-> Hard wrap at 設(shè)置為120
    (2). Preference->Editor->Code Style->Java ->Wrapping and Braces -> 勾選"Line breaks"和"Ensure right margin is not exceeded"
  5. 方法內(nèi)部不同邏輯,不同語(yǔ)義,不同業(yè)務(wù)之間可以使用換行,代碼任意位置不能出現(xiàn)多余1行的空行.IDEA設(shè)置:
    Preference->Editor->Code Style->Java->Blank Lines->所有超過(guò)1的選項(xiàng)設(shè)置為1.
  6. 空格使用規(guī)范:
    (1). if/for/while/switch/do 等保留字與括號(hào)之間都必須加空格吹艇。
    (2). 小括號(hào)內(nèi)左右第一個(gè)字符和小括號(hào)間不留空格
    (3). 左大括號(hào)前加空格
    (4). 二目三目運(yùn)算符的左右兩邊都要加空格
    (5). 雙斜線和注釋內(nèi)容間僅使用一個(gè)空格
    (6). 方法參數(shù)間使用一個(gè)空格
  7. 大括號(hào)使用規(guī)范:
    (1). 左大括號(hào)前不換行
    (2). 左大括號(hào)后換行
    (3). 右大括號(hào)前有else等不換行
    (4). 右大括號(hào)表示終止需換行
    (5). 大括號(hào)內(nèi)為空,可寫成{},并不換行
  8. 推薦單個(gè)方法勿超過(guò)80行,超過(guò)80行考慮提取方法,保持單一責(zé)任原則.

4. OOP 規(guī)約

  1. 所有靜態(tài)變量,常量,方法,都使用類名調(diào)用,勿使用對(duì)象調(diào)用.避免增加編譯器解析成本.
  2. 所有覆寫方法,需要加上@Override注解,避免方法名寫錯(cuò),編譯時(shí)不報(bào)錯(cuò).推薦使用快捷鍵調(diào)用"Override Members"覆寫方法,避免出錯(cuò).
  3. 避免使用Object作為參數(shù),盡量不適用可變參數(shù).
  4. 不能使用過(guò)時(shí)的類或方法.
  5. Object的equals方法容易拋空指針異常,應(yīng)使用常量來(lái)調(diào)用equals:"cache".equals(xxx),或者使用Objects.equals(a,b)
  6. POJO類屬性強(qiáng)制使用包裝數(shù)據(jù)類型,如當(dāng)數(shù)據(jù)庫(kù)查詢時(shí)結(jié)果可能為null,使用基本數(shù)據(jù)類型去接收會(huì)有NPE風(fēng)險(xiǎn).并且基本數(shù)據(jù)類型的默認(rèn)值可能會(huì)帶來(lái)錯(cuò)誤信息,比如當(dāng)調(diào)用接口沒(méi)有返回值時(shí),默認(rèn)的0,false等會(huì)帶來(lái)歧義.null值表示出額外的信息:調(diào)用失敗,服務(wù)器未返回該值等.
  7. 構(gòu)造方法里不能加入業(yè)務(wù)邏輯,初始化邏輯應(yīng)放在init方法中.
  8. POJO類必須重寫toString()方法(Kotlin的data類默認(rèn)已添加該方法,無(wú)需手動(dòng)添加)
  9. 重載方法應(yīng)按順序放在一起,構(gòu)造方法相同.在此基礎(chǔ)上的方法置放順序:public,proteced > private > getter/setter
  10. getter/setter方法應(yīng)保持簡(jiǎn)單的get/set動(dòng)作,不應(yīng)插入業(yè)務(wù)邏輯.
  11. 循環(huán)體內(nèi),字符串的連接使用StringBuilder的append方法,使用字符串直接+連接會(huì)造成每次循環(huán)new出StringBuilder對(duì)象.(Kotlin可使用"${var1}var2"方式連接)
  12. 方法,屬性權(quán)限應(yīng)給滿足使用的最小權(quán)限.
    (1). 類內(nèi)使用:private
    (2). 包內(nèi)和子類使用:protected.
    過(guò)于寬泛的權(quán)限會(huì)導(dǎo)致不當(dāng)調(diào)用泛濫,不利于解耦.(一旦在其他地方被調(diào)用,這個(gè)方法,屬性就不止屬于類自己了)
  13. 不能再foreach循環(huán)里進(jìn)行元素的remove/add操作.可能會(huì)引起運(yùn)行時(shí)異常.
  14. 為了降低記憶負(fù)擔(dān),Map中不要使用null作為key,只有HashMap和TreeMap可以存儲(chǔ)null的value.
  15. 合理利用好集合的有序性(sort)和穩(wěn)定性(order),避免集合的無(wú)序性(unsort)和
    不穩(wěn)定性(unorder)帶來(lái)的負(fù)面影響。
    有序性是指遍歷的結(jié)果是按某種比較規(guī)則依次排列的鼻忠。穩(wěn)定性指集合每次遍歷的元素次
    序是一定的兔院。如:ArrayList 是 order/unsort;HashMap 是 unorder/unsort袍暴;TreeSet 是order/sort踩晶。
  16. 可以用用Set的唯一性快速去重,不要使用List的contains方法進(jìn)行遍歷對(duì)比去重.
  17. 表達(dá)異常的分支,少用if-else,減少if-else嵌套,嵌套不能超過(guò)3層,消滅箭頭語(yǔ)句,盡量使用衛(wèi)語(yǔ)句(剪枝邏輯):
No:

if(condition1){
    
} esle if(condition2) {
    
} else if(condition3) {
    
}

Yes:

if(condition1){
    
}
if(condition2){
    
}
if(condition3){
    
}
  1. 不要直接使用復(fù)雜的判斷邏輯,將復(fù)雜的判斷表達(dá)式賦值給一個(gè)有意義的布爾變量,調(diào)代碼可讀性.
正例:
// 偽代碼如下
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
 ...
}
反例:
if ((file.open(fileName, "w") != null) && (...) || (...)) {
 ...
}
  1. 校驗(yàn)參數(shù)規(guī)范:
    (1). 執(zhí)行流程較為復(fù)雜的方法需要進(jìn)行參數(shù)校驗(yàn)(FastFail)
    (2). 與用戶輸入相關(guān)方法需校驗(yàn)參數(shù).
    (3). 對(duì)外提供的開放接口需校驗(yàn)參數(shù).
    (4). 較為底層且調(diào)用次數(shù)頻繁方法不需要校驗(yàn)參數(shù).

5. 注釋規(guī)約

  1. 類、類屬性唧躲、類方法的注釋必須使用 Javadoc 規(guī)范,使用/*內(nèi)容/格式伸眶,不得使用
    // xxx 方式惊窖。
    說(shuō)明:在 IDE 編輯窗口中,Javadoc方式會(huì)提示相關(guān)注釋厘贼,生成Javadoc可以正確輸出相應(yīng)注釋界酒;在IDE中,工程調(diào)用方法時(shí)嘴秸,不進(jìn)入方法即可懸浮提示方法毁欣、參數(shù)庇谆、返回值的意義,提高閱讀效率凭疮。
  2. 所有的抽象方法(包括接口中的方法)必須要用Javadoc注釋饭耳、除了返回值、參數(shù)执解、異常說(shuō)明外寞肖,還必須指出該方法做什么事情,實(shí)現(xiàn)什么功能衰腌。
    說(shuō)明:對(duì)子類的實(shí)現(xiàn)要求新蟆,或者調(diào)用注意事項(xiàng),需一并說(shuō)明右蕊。
  3. 方法內(nèi)部單行注釋琼稻,在被注釋語(yǔ)句上方另起一行,使用//注釋饶囚。方法內(nèi)部多行注釋
    使用/* */注釋帕翻,注意與代碼對(duì)齊。
  4. 注釋掉的代碼用注釋說(shuō)明注釋原因,注釋原因用///注釋,如果不再使用,刪除該代碼,使用版本控制追溯.
  5. 對(duì)于注釋的要求:
    (1). 能夠準(zhǔn)確反應(yīng)設(shè)計(jì)思想和代碼邏輯
    (2). 能夠描述業(yè)務(wù)含義萝风,使別的程序員能夠迅速了解到代碼背后的信息嘀掸。
    (3). 保持和代碼的同步.
    (4). 盡量使用常用,簡(jiǎn)單的英語(yǔ)進(jìn)行注釋.可搭配翻譯使用,避免中式英語(yǔ).
    (5). 使用最簡(jiǎn)練的語(yǔ)言寫注釋,好的命名、代碼結(jié)構(gòu)是自解釋的闹丐,避免過(guò)多過(guò)濫的注釋.
反例:
// put elephant into fridge
put(elephant, fridge);
方法名 put横殴,加上兩個(gè)有意義的變量名 elephant 和 fridge被因,已經(jīng)說(shuō)明了這是在干什么卿拴,語(yǔ)
義清晰的代碼不需要額外的注釋。
  1. 特殊注釋標(biāo)記
    (1). 待辦事宜(TODO):( 標(biāo)記人梨与,標(biāo)記時(shí)間堕花,[預(yù)計(jì)處理時(shí)間])
    (2). 錯(cuò)誤,不能工作(FIXME):(標(biāo)記人粥鞋,標(biāo)記時(shí)間缘挽,[預(yù)計(jì)處理時(shí)間])

6. 異常處理規(guī)約

  1. 異常因使用最小粒度進(jìn)行捕獲,不能使用一個(gè)exception進(jìn)行捕獲.注意多個(gè)異常排列的順序.
  2. 捕獲異常應(yīng)盡量catch最小的單元,不要catch過(guò)多內(nèi)容.
  3. 捕獲異常之后必須處理.推薦異常進(jìn)行日志記錄上報(bào)(Do not swallow)
  4. 資源需要在finally中釋放,推薦使用try-with-resource的方式.
  5. 級(jí)聯(lián)調(diào)用 obj.getA().getB().getC();一連串調(diào)用呻粹,易產(chǎn)生 NPE壕曼。使用 JDK8 的 Optional 類來(lái)防止 NPE 問(wèn)題。(Kotlin可使用?.調(diào)用方式處理)
if(obj == null){
  return;
}
if(a == null){
  return;
}
if(b == null){
  return;
}
b.getC();

if(obj?.getA()?.getB()?.getC() == null){
  return
}

obj!!.getA();

7. 日志規(guī)約

  1. 日志文件至少保存15天,有些異常是以"周"為頻次發(fā)生的.
  2. 對(duì) trace/debug/info 級(jí)別的日志輸出等浊,必須使用條件輸出形式或者使用占位符的方
    式腮郊。
反例
logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);

正例:(條件)建設(shè)采用如下方式
if (logger.isDebugEnabled()) {
logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
}

正例:(占位符)
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol); 

Kotlin中可采取
logger.debug("Processing trade with id: ${id} and symbol: ${symbol}");
  1. 日志不可重復(fù)打印,冗余打印,保持精簡(jiǎn).
  2. 異常日志應(yīng)記錄必要的現(xiàn)場(chǎng)信息和堆棧信息
正例:
logger.error(各類參數(shù)或者對(duì)象 toString() + "_" + e.getMessage(), e);
  1. 生產(chǎn)環(huán)境應(yīng)關(guān)閉debug日志.(遠(yuǎn)程調(diào)試除外)

討論

  1. 所有的枚舉類型字段必須要有注釋,說(shuō)明每個(gè)數(shù)據(jù)項(xiàng)的用途筹燕。
  2. 每個(gè)switch需要帶上default,case語(yǔ)句如果沒(méi)有break語(yǔ)句,需要在末尾注釋// fall down

TODO:單元測(cè)試規(guī)約

參考:
阿里巴巴java開發(fā)手冊(cè)
插件使用文檔
阿里巴巴Android開發(fā)手冊(cè)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末轧飞,一起剝皮案震驚了整個(gè)濱河市衅鹿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌过咬,老刑警劉巖大渤,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異掸绞,居然都是意外死亡泵三,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門衔掸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)切黔,“玉大人,你說(shuō)我怎么就攤上這事具篇∥诚迹” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵驱显,是天一觀的道長(zhǎng)诗芜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)埃疫,這世上最難降的妖魔是什么伏恐? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮栓霜,結(jié)果婚禮上翠桦,老公的妹妹穿的比我還像新娘。我一直安慰自己胳蛮,他們只是感情好销凑,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仅炊,像睡著了一般斗幼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抚垄,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天蜕窿,我揣著相機(jī)與錄音,去河邊找鬼呆馁。 笑死桐经,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浙滤。 我是一名探鬼主播阴挣,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瓷叫!你這毒婦竟也來(lái)了屯吊?” 一聲冷哼從身側(cè)響起送巡,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盒卸,沒(méi)想到半個(gè)月后骗爆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔽介,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年摘投,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虹蓄。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡犀呼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出薇组,到底是詐尸還是另有隱情外臂,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布律胀,位于F島的核電站宋光,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏炭菌。R本人自食惡果不足惜罪佳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望黑低。 院中可真熱鬧赘艳,春花似錦、人聲如沸克握。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)玛荞。三九已至娇掏,卻和暖如春呕寝,著一層夾襖步出監(jiān)牢的瞬間勋眯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工下梢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留客蹋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓孽江,卻偏偏與公主長(zhǎng)得像讶坯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岗屏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容