Android編碼規(guī)范
源文件基礎(chǔ)
文件名
源文件以其最頂層的類(lèi)名來(lái)命名,大小寫(xiě)敏感,文件擴(kuò)展名為.java。
文件編碼:UTF-8
源文件編碼格式為 UTF-8压彭。
特殊字符
空白字符
除了行結(jié)束符序列,ASCII水平空格字符(0×20渗常,即空格)是源文件中唯一允許出現(xiàn)的空白字符壮不,這意味著:
所有其它字符串中的空白字符都要進(jìn)行轉(zhuǎn)義。
制表符不用于縮進(jìn)(可以在IDE中Tab鍵設(shè)置為若干個(gè)空格)皱碘。
特殊轉(zhuǎn)義序列
對(duì)于具有特殊轉(zhuǎn)義序列的任何字符(\b, \t, \n, \f, \r, \”, \’及)询一,我們使用它的轉(zhuǎn)義序列,而不是相應(yīng)的八進(jìn)制(比如\012)或Unicode(比如\u000a)轉(zhuǎn)義。
非ASCII字符
對(duì)于剩余的非ASCII字符健蕊,是使用實(shí)際的Unicode字符(比如∞)菱阵,還是使用等價(jià)的Unicode轉(zhuǎn)義符(比如\u221e),取決于哪個(gè)能讓代碼更易于閱讀和理解缩功。
注意:在使用Unicode轉(zhuǎn)義符或是一些實(shí)際的Unicode字符時(shí)晴及,建議做些注釋給出解釋?zhuān)@有助于別人閱讀和理解。
例如:
String unitAbbrev = "μs"; | 贊嫡锌,即使沒(méi)有注釋也非常清晰
String unitAbbrev = "\u03bcs"; // "μs" | 允許虑稼,但沒(méi)有理由要這樣做
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" | 允許,但這樣做顯得笨拙還容易出錯(cuò)
String unitAbbrev = "\u03bcs"; | 很糟势木,讀者根本看不出這是什么
return '\ufeff' + content; // byte order mark | Good蛛倦,對(duì)于非打印字符,使用轉(zhuǎn)義跟压,并在必要時(shí)寫(xiě)上注釋
注意:永遠(yuǎn)不要由于害怕某些程序可能無(wú)法正確處理非ASCII字符而讓你的代碼可讀性變差胰蝠。當(dāng)程序無(wú)法正確處理非ASCII字符時(shí)歼培,它自然無(wú)法正確運(yùn)行震蒋, 你就會(huì)去fix這些問(wèn)題的了。(言下之意就是大膽去用非ASCII字符躲庄,如果真的有需要的話)
源文件結(jié)構(gòu)
一個(gè)源文件包含(按順序地):
許可證或版權(quán)信息(如有需要)
package語(yǔ)句
import語(yǔ)句
一個(gè)頂級(jí)類(lèi)(只有一個(gè))以上每個(gè)部分之間用一個(gè)空行隔開(kāi)查剖。
許可證或版權(quán)信息
如果一個(gè)文件包含許可證或版權(quán)信息,那么它應(yīng)當(dāng)被放在文件最前面噪窘。
package語(yǔ)句
package 語(yǔ)句不換行笋庄,列限制并不適用于package語(yǔ)句。(即package語(yǔ)句寫(xiě)在一行里)
import語(yǔ)句
import不要使用通配符
即倔监,不要出現(xiàn)類(lèi)似這樣的import語(yǔ)句:import java.util.*;
不要換行
import語(yǔ)句不換行直砂,列限制(4.4節(jié))并不適用于import語(yǔ)句。(每個(gè)import語(yǔ)句獨(dú)立成行)
間距
import語(yǔ)句分組浩习,每組由一個(gè)空行分隔:
類(lèi)聲明
只有一個(gè)頂級(jí)
類(lèi)聲明每個(gè)頂級(jí)類(lèi)都在一個(gè)與它同名的源文件中(當(dāng)然静暂,還包含.java后綴)。
例外:package-info.java谱秽,該文件中可沒(méi)有package-info類(lèi)洽蛀。
類(lèi)成員順序
類(lèi)的成員順序?qū)σ讓W(xué)性有很大的影響,但這也不存在唯一的通用法則疟赊。不同的類(lèi)對(duì)成員的排序可能是不同的郊供。
最重要的一點(diǎn),每個(gè)類(lèi)應(yīng)該以某種邏輯去排序它的成員近哟,維護(hù)者應(yīng)該要能解釋這種排序邏輯驮审。比如, 新的方法不能總是習(xí)慣性地添加到類(lèi)的結(jié)尾,因?yàn)檫@樣就是按時(shí)間順序而非某種邏輯來(lái)排序的头岔。
區(qū)塊劃分
建議使用注釋將源文件分為明顯的區(qū)塊塔拳,區(qū)塊劃分如下
常量聲明區(qū)
UI控件成員變量聲明區(qū)
普通成員變量聲明區(qū)
內(nèi)部接口聲明區(qū)
初始化相關(guān)方法區(qū)
事件響應(yīng)方法區(qū)
普通邏輯方法區(qū)
重載的邏輯方法區(qū)
發(fā)起異步任務(wù)方法區(qū)
異步任務(wù)回調(diào)方法區(qū)
生命周期回調(diào)方法區(qū)(出去onCreate()方法)
內(nèi)部類(lèi)聲明區(qū)
類(lèi)成員排列通用規(guī)則
按照發(fā)生的先后順序排列
常量按照使用先后排列
UI控件成員變量按照l(shuí)ayout文件中的先后順序排列
普通成員變量按照使用的先后順序排列
方法基本上都按照調(diào)用的先后順序在各自區(qū)塊中排列
相關(guān)功能作為小區(qū)塊放在一起(或者封裝掉)
重載:永不分離
當(dāng)一個(gè)類(lèi)有多個(gè)構(gòu)造函數(shù),或是多個(gè)同名方法峡竣,這些函數(shù)/方法應(yīng)該按順序出現(xiàn)在一起靠抑,中間不要放進(jìn)其它函數(shù)/方法。
塊狀結(jié)構(gòu)
塊狀結(jié)構(gòu)(block-like construct)指的是一個(gè)類(lèi)适掰,方法或構(gòu)造函數(shù)的主體颂碧。需要注意的是,數(shù)組初始化中的初始值可被選擇性地視為塊狀結(jié)構(gòu)类浪。
大括號(hào)
使用大括號(hào)(即使是可選的)
大括號(hào)與if, else, for, do, while語(yǔ)句一起使用载城,即使只有一條語(yǔ)句(或是空),也應(yīng)該把大括號(hào)寫(xiě)上费就。
非空塊:K & R 風(fēng)格
對(duì)于非空塊和塊狀結(jié)構(gòu)诉瓦,大括號(hào)遵循 Kernighan 和 Ritchie 風(fēng)格 (Egyptian brackets):
左大括號(hào)前不換行
左大括號(hào)后換行
右大括號(hào)前換行
如果右大括號(hào)是一個(gè)語(yǔ)句、函數(shù)體或類(lèi)的終止力细,則右大括號(hào)后換行; 否則不換行睬澡。
例如,如果右大括號(hào)后面是else或逗號(hào)眠蚂,則不換行煞聪。
示例:
return new MyClass() {
@Override public void method() {
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
}
}
};
空塊:可以用簡(jiǎn)潔版本
一個(gè)空的塊狀結(jié)構(gòu)里什么也不包含,大括號(hào)可以簡(jiǎn)潔地寫(xiě)成{}逝慧,不需要換行昔脯。
例外:如果它是一個(gè)多塊語(yǔ)句的一部分(if/else 或 try/catch/finally) ,即使大括號(hào)內(nèi)沒(méi)內(nèi)容笛臣,右大括號(hào)也要換行云稚。
示例:
void doNothing() {}
塊縮進(jìn):4個(gè)空格
每當(dāng)開(kāi)始一個(gè)新的塊,縮進(jìn)增加4個(gè)空格沈堡,當(dāng)塊結(jié)束時(shí)静陈,縮進(jìn)返回先前的縮進(jìn)級(jí)別□庵縮進(jìn)級(jí)別適用于代碼和注釋窿给。(見(jiàn)4.1.2節(jié)中的代碼示例)
換行,空行
一個(gè)語(yǔ)句一行率拒,每個(gè)語(yǔ)句后要換行崩泡。
每個(gè)代碼塊之間空一行。
空格
- 運(yùn)算符的兩邊要空一格
- 左大括號(hào)之前空一格c
- 右大括號(hào)之后有語(yǔ)句的話空一格
- if之后空一格猬膨,else前后都空一格
- catch角撞, finally前后都空一格
- 逗號(hào)后面空一格
- 單詞之間空一格呛伴,不要多
- 類(lèi)型強(qiáng)轉(zhuǎn)前后各空一格
- 控制語(yǔ)句的條件的括號(hào)前后空一格(if、switch谒所、while...)
- 以上規(guī)則重疊只空一格
列限制:80或100
一個(gè)項(xiàng)目可以選擇一行80個(gè)字符或100個(gè)字符的列限制热康,除了下述例外,任何一行如果超過(guò)這個(gè)字符數(shù)限制劣领,必須自動(dòng)換行姐军。
例外:
不可能滿足列限制的行(例如,Javadoc中的一個(gè)長(zhǎng)URL尖淘,或是一個(gè)長(zhǎng)的JSNI方法參考)奕锌。
package和import語(yǔ)句。
注釋中那些可能被剪切并粘貼到shell中的命令行村生。
自動(dòng)換行
術(shù)語(yǔ)說(shuō)明:一般情況下惊暴,一行長(zhǎng)代碼為了避免超出列限制(80或100個(gè)字符)而被分為多行,我們稱(chēng)之為自動(dòng)換行(line-wrapping)趁桃。我們并沒(méi)有全面辽话,確定性的準(zhǔn)則來(lái)決定在每一種情況下如何自動(dòng)換行。很多時(shí)候卫病,對(duì)于同一段代碼會(huì)有好幾種有效的自動(dòng)換行方式油啤。
注意:提取方法或局部變量可以在不換行的情況下解決代碼過(guò)長(zhǎng)的問(wèn)題(是合理縮短命名長(zhǎng)度吧)
從哪里斷開(kāi)
自動(dòng)換行的基本準(zhǔn)則是:更傾向于在更高的語(yǔ)法級(jí)別處斷開(kāi)。
- 如果在非賦值運(yùn)算符處斷開(kāi)忽肛,那么在該符號(hào)前斷開(kāi)(比如+村砂,它將位于下一行)烂斋。注意:這一點(diǎn)與 Google 其它語(yǔ)言的編程風(fēng)格不同(如 C++ 和 JavaScript )屹逛。
- 這條規(guī)則也適用于以下”類(lèi)運(yùn)算符”符號(hào):點(diǎn)分隔符(.),類(lèi)型界限中的 &()汛骂,catch 塊中的管道符號(hào)(catch (FooException | BarException e)
- 如果在賦值運(yùn)算符處斷開(kāi)罕模,通常的做法是在該符號(hào)后斷開(kāi)(比如=,它與前面的內(nèi)容留在同一行)帘瞭。這條規(guī)則也適用于foreach語(yǔ)句中的分號(hào)淑掌。
- 方法名或構(gòu)造函數(shù)名與左括號(hào)留在同一行。
- 逗號(hào)(,)與其前面的內(nèi)容留在同一行蝶念。
自動(dòng)換行時(shí)縮進(jìn)至少+8個(gè)空格
自動(dòng)換行時(shí)抛腕,第一行后的每一行至少比第一行多縮進(jìn)8個(gè)空格(注意:制表符不用于縮進(jìn)。見(jiàn)2.3.1節(jié))媒殉。當(dāng)存在連續(xù)自動(dòng)換行時(shí)担敌,縮進(jìn)可能會(huì)多縮進(jìn)不只8個(gè)空格(語(yǔ)法元素存在多級(jí)時(shí))。一般而言廷蓉,兩個(gè)連續(xù)行使用相同的縮進(jìn)當(dāng)且僅當(dāng)它們開(kāi)始于同級(jí)語(yǔ)法元素全封。
不鼓勵(lì)使用可變數(shù)目的空格來(lái)對(duì)齊前面行的符號(hào)。
空白
垂直空白
以下情況需要使用一個(gè)空行:
- 類(lèi)內(nèi)連續(xù)的成員之間:字段,構(gòu)造函數(shù)刹悴,方法行楞,嵌套類(lèi),靜態(tài)初始化塊土匀,實(shí)例初始化塊子房。 例外: 兩個(gè)連續(xù)字段之間的空行是可選的,用于字段的空行主要用來(lái)對(duì)字段進(jìn)行邏輯分組就轧。
- 在函數(shù)體內(nèi)池颈,語(yǔ)句的邏輯分組間使用空行。
- 類(lèi)內(nèi)的第一個(gè)成員前或最后一個(gè)成員后的空行是可選的(既不鼓勵(lì)也不反對(duì)這樣做钓丰,視個(gè)人喜好而定)躯砰。
- 要滿足本文檔中其他節(jié)的空行要求(比如3.3節(jié):import語(yǔ)句)
- 多個(gè)連續(xù)的空行是允許的,但沒(méi)有必要這樣做(我們也不鼓勵(lì)這樣做)携丁。
水平空白
除了語(yǔ)言需求和其它規(guī)則琢歇,并且除了文字,注釋和Javadoc用到單個(gè)空格梦鉴,單個(gè)ASCII空格也出現(xiàn)在以下幾個(gè)地方:
分隔任何保留字與緊隨其后的左括號(hào)(()(如if, for catch等)李茫。
分隔任何保留字與其前面的右大括號(hào)(})(如else, catch)。
-
在任何左大括號(hào)前({)肥橙,兩個(gè)例外:
- @SomeAnnotation({a, b})(不使用空格)魄宏。
- String[][] x = foo;(大括號(hào)間沒(méi)有空格,見(jiàn)下面的Note)存筏。
-
在任何二元或三元運(yùn)算符的兩側(cè)宠互。這也適用于以下”類(lèi)運(yùn)算符”符號(hào):
- 類(lèi)型界限中的&()。
- catch塊中的管道符號(hào)(catch (FooException | BarException e)椭坚。
- foreach語(yǔ)句中的分號(hào)予跌。
在, : ;及右括號(hào)())后
如果在一條語(yǔ)句后做注釋?zhuān)瑒t雙斜杠(//)兩邊都要空格。這里可以允許多個(gè)空格善茎,但沒(méi)有必要券册。
類(lèi)型和變量之間:List list。
數(shù)組初始化中垂涯,大括號(hào)內(nèi)的空格是可選的烁焙,即new int[] {5, 6}和new int[] { 5, 6 }都是可以的。
注意:這個(gè)規(guī)則并不要求或禁止一行的開(kāi)關(guān)或結(jié)尾需要額外的空格耕赘,只對(duì)內(nèi)部空格做要求骄蝇。
水平對(duì)齊(可選)
術(shù)語(yǔ)說(shuō)明:水平對(duì)齊指的是通過(guò)增加可變數(shù)量的空格來(lái)使某一行的字符與上一行的相應(yīng)字符對(duì)齊。
以下示例先展示未對(duì)齊的代碼鞠苟,然后是對(duì)齊的代碼:
private int x; // this is fine
private Color color; // this too
private int x; // permitted, but future edits
private Color color; // may leave it unaligned
注意:對(duì)齊可增加代碼可讀性乞榨,但它為日后的維護(hù)帶來(lái)問(wèn)題秽之。考慮未來(lái)某個(gè)時(shí)候吃既,我們需要修改一堆對(duì)齊的代碼中的一行考榨。
這可能導(dǎo)致原本很漂亮的對(duì)齊代碼變得錯(cuò)位。很可能它會(huì)提示你調(diào)整周?chē)a的空白來(lái)使這一堆代碼重新水平對(duì)齊(比如程序員想保持這種水平對(duì)齊的風(fēng)格)鹦倚。
這就會(huì)讓你做許多的無(wú)用功河质,增加了reviewer的工作并且可能導(dǎo)致更多的合并沖突。
用小括號(hào)來(lái)限定組:推薦
除非作者和reviewer都認(rèn)為去掉小括號(hào)也不會(huì)使代碼被誤解震叙,或是去掉小括號(hào)能讓代碼更易于閱讀掀鹅,否則我們不應(yīng)該去掉小括號(hào)。
我們沒(méi)有理由假設(shè)讀者能記住整個(gè)Java運(yùn)算符優(yōu)先級(jí)表媒楼。
具體結(jié)構(gòu)
枚舉類(lèi)
枚舉常量間用逗號(hào)隔開(kāi)乐尊,換行可選。
沒(méi)有方法和文檔的枚舉類(lèi)可寫(xiě)成數(shù)組初始化的格式:
private enum Suit {
CLUBS,
HEARTS,
SPADES,
DIAMONDS
}
由于枚舉類(lèi)也是一個(gè)類(lèi)划址,因此所有適用于其它類(lèi)的格式規(guī)則也適用于枚舉類(lèi)扔嵌。
變量聲明
每次只聲明一個(gè)變量
不要使用組合聲明,比如int a, b;夺颤。
需要時(shí)才聲明痢缎,并盡快進(jìn)行初始化
不要在一個(gè)代碼塊的開(kāi)頭把局部變量一次性都聲明了(這是c語(yǔ)言的做法),而是在第一次需要使用它時(shí)才聲明世澜。 局部變量在聲明時(shí)最好就進(jìn)行初始化独旷,或者聲明后盡快進(jìn)行初始化。
數(shù)組
數(shù)組初始化:可寫(xiě)成塊狀結(jié)構(gòu)
數(shù)組初始化可以寫(xiě)成塊狀結(jié)構(gòu)寥裂,比如嵌洼,下面的寫(xiě)法都是OK的:
new int[] {
0, 1, 2, 3
}
new int[] {
0,
1,
2,
3
}
new int[] {
0, 1,
2, 3
}
new int[]
{0, 1, 2, 3}
非C風(fēng)格的數(shù)組聲明
中括號(hào)是類(lèi)型的一部分:String[] args, 而非 String args[]抚恒。
switch語(yǔ)句
術(shù)語(yǔ)說(shuō)明:switch塊的大括號(hào)內(nèi)是一個(gè)或多個(gè)語(yǔ)句組咱台。
每個(gè)語(yǔ)句組包含一個(gè)或多個(gè)switch標(biāo)簽(case FOO:或default:)络拌,后面跟著一條或多條語(yǔ)句俭驮。
縮進(jìn)
與其它塊狀結(jié)構(gòu)一致,switch塊中的內(nèi)容縮進(jìn)為2個(gè)空格春贸。每個(gè)switch標(biāo)簽后新起一行混萝,再縮進(jìn)2個(gè)空格,寫(xiě)下一條或多條語(yǔ)句萍恕。
Fall-through:注釋
在一個(gè)switch塊內(nèi)逸嘀,每個(gè)語(yǔ)句組要么通過(guò)break, continue, return或拋出異常來(lái)終止,要么通過(guò)一條注釋來(lái)說(shuō)明程序?qū)⒗^續(xù)執(zhí)行到下一個(gè)語(yǔ)句組允粤, 任何能表達(dá)這個(gè)意思的注釋都是OK的(典型的是用// fall through)崭倘。這個(gè)特殊的注釋并不需要在最后一個(gè)語(yǔ)句組(一般是default)中出現(xiàn)翼岁。
示例:
switch (input) {
case 1:
case 2:
prepareOneOrTwo(); // fall through
case 3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}
default的情況要寫(xiě)出來(lái)
每個(gè)switch語(yǔ)句都包含一個(gè)default語(yǔ)句組,即使它什么代碼也不包含司光。
注解(Annotations)
注解緊跟在文檔塊后面琅坡,應(yīng)用于類(lèi)、方法和構(gòu)造函數(shù)残家,一個(gè)注解獨(dú)占一行榆俺。這些換行不屬于自動(dòng)換行(第4.5節(jié),自動(dòng)換行)坞淮,因此縮進(jìn)級(jí)別不變茴晋。
例如:
@Nullable public String getNameIfPresent() { … }
例外:?jiǎn)蝹€(gè)的注解可以和簽名的第一行出現(xiàn)在同一行。
例如:
@Override public int hashCode() { … }
應(yīng)用于字段的注解緊隨文檔塊出現(xiàn)回窘,應(yīng)用于字段的多個(gè)注解允許與字段出現(xiàn)在同一行诺擅。
例如:
@Partial @Mock DataLoader loader;
參數(shù)和局部變量注解沒(méi)有特定規(guī)則。
注釋
塊注釋風(fēng)格
塊注釋與其周?chē)拇a在同一縮進(jìn)級(jí)別啡直。它們可以是/ … /風(fēng)格掀虎,也可以是// …風(fēng)格。對(duì)于多行的/ … /注釋?zhuān)罄m(xù)行必須從開(kāi)始付枫, 并且與前一行的對(duì)齊烹玉。
以下示例注釋都是OK的。
/** This is // And so /* Or you can
* okay. // is this. * even do this. */
*/
注釋不要封閉在由星號(hào)或其它字符繪制的框架里阐滩。
注意:在寫(xiě)多行注釋時(shí)二打,如果你希望在必要時(shí)能重新?lián)Q行(即注釋像段落風(fēng)格一樣),那么使用/ … /
掂榔。
Modifiers
類(lèi)和成員的modifiers如果存在继效,則按Java語(yǔ)言規(guī)范中推薦的順序出現(xiàn)。
public protected private abstract static final transient Volatile synchronized native strictfp
常見(jiàn)命名法
- 小駝峰式命名法(lower camel case):
第一個(gè)單字以小寫(xiě)字母開(kāi)始装获,第二個(gè)單字的首字母大寫(xiě)瑞信。例如:firstName、lastName穴豫。 - 大駝峰式命名法(upper camel case):
每一個(gè)單字的首字母都采用大寫(xiě)字母凡简,例如:FirstName、LastName精肃、CamelCase秤涩,也被稱(chēng)為 Pascal(帕斯卡) 命名法。 - 匈牙利命名法:
通過(guò)在變量名之前增加小寫(xiě)字母的符號(hào)前綴司抱,以標(biāo)識(shí)變量的屬性筐眷、類(lèi)型、作用域等參數(shù)习柠。簡(jiǎn)單地說(shuō)匀谣,即“變量名=屬性+類(lèi)型+對(duì)象描述”的形式照棋。 - 下劃線命名法:
單詞與單詞間用下劃線做間隔。例如:tv_title
標(biāo)識(shí)符類(lèi)型的規(guī)則
對(duì)所有標(biāo)識(shí)符都通用的規(guī)則
標(biāo)識(shí)符只能使用ASCII字母和數(shù)字武翎,因此每個(gè)有效的標(biāo)識(shí)符名稱(chēng)都能匹配正則表達(dá)式\w+必怜。
包名
包名全部小寫(xiě),連續(xù)的單詞只是簡(jiǎn)單地連接起來(lái)后频,不使用下劃線梳庆。
采用反域名命名規(guī)則,全部使用小寫(xiě)字母卑惜。一級(jí)包名為com膏执,二級(jí)包名為xx(可以是公司或則個(gè)人的隨便),三級(jí)包名根據(jù)應(yīng)用進(jìn)行命名露久,四級(jí)包名為模塊名或?qū)蛹?jí)名更米。
包名 | 此包中包含 |
---|---|
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).activity | 頁(yè)面用到的Activity類(lèi) (activitie層級(jí)名用戶(hù)界面層) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).base | 基礎(chǔ)共享的類(lèi) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).adapter | 頁(yè)面用到的Adapter類(lèi) (適配器的類(lèi)) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).util | 此包中包含:公共工具方法類(lèi)(util模塊名) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).bean | 下面可分:vo、po毫痕、dto 此包中包含:JavaBean類(lèi) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).model | 此包中包含:模型類(lèi) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).db | 數(shù)據(jù)庫(kù)操作類(lèi) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).view | (或者 com.xx.應(yīng)用名稱(chēng)縮寫(xiě).widget ) 自定義的View類(lèi)等 |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).service | Service服務(wù) |
com.xx.應(yīng)用名稱(chēng)縮寫(xiě).receiver | BroadcastReceiver服務(wù) |
注意:
如果項(xiàng)目采用MVP征峦,所有M、V消请、P抽取出來(lái)的接口都放置在相應(yīng)模塊的i包下栏笆,所有的實(shí)現(xiàn)都放置在相應(yīng)模塊的impl下
類(lèi)名
類(lèi)名都以大駝峰命名法(UpperCamelCase)風(fēng)格編寫(xiě)。
類(lèi)名通常是名詞或名詞短語(yǔ)臊泰,接口名稱(chēng)有時(shí)可能是形容詞或形容詞短語(yǔ)◎燃樱現(xiàn)在還沒(méi)有特定的規(guī)則或行之有效的約定來(lái)命名注解類(lèi)型。
名詞缸逃,采用大駝峰命名法针饥,盡量避免縮寫(xiě),除非該縮寫(xiě)是眾所周知的需频, 比如HTML,URL丁眼,如果類(lèi)名稱(chēng)中包含單詞縮寫(xiě),則單詞縮寫(xiě)的每個(gè)字母均應(yīng)大寫(xiě)昭殉。
類(lèi) | 描述 | 例如 |
---|---|---|
Activity 類(lèi) | Activity為后綴標(biāo)識(shí) | 歡迎頁(yè)面類(lèi)WelcomeActivity |
Adapter類(lèi) | Adapter 為后綴標(biāo)識(shí) | 新聞詳情適配器 NewDetailAdapter |
解析類(lèi) | Parser為后綴標(biāo)識(shí) | 首頁(yè)解析類(lèi)HomePosterParser |
工具方法類(lèi) | Util或Manager為后綴標(biāo)識(shí)(與系統(tǒng)或第三方的Utils區(qū)分)或功能+Util | 線程池管理類(lèi):ThreadPoolManager日志工具類(lèi):LogUtil(Logger也可)打印工具類(lèi):PrinterUtil |
數(shù)據(jù)庫(kù)類(lèi) | 以DBHelper后綴標(biāo)識(shí) | 新聞數(shù)據(jù)庫(kù):NewDBHelper |
Service類(lèi) | 以Service為后綴標(biāo)識(shí) | 時(shí)間服務(wù)TimeServiceBroadcast |
Receiver類(lèi) | 以Receiver為后綴標(biāo)識(shí) | 推送接收J(rèn)PushReceiver |
ContentProvider | 以Provider為后綴標(biāo)識(shí) | |
自定義的共享基礎(chǔ)類(lèi) | 以Base開(kāi)頭 | BaseActivity,BaseFragment |
測(cè)試類(lèi)的命名以它要測(cè)試的類(lèi)的名稱(chēng)開(kāi)始苞七,以Test結(jié)束。
例如:HashTest 或 HashIntegrationTest饲化。
接口(interface):命名規(guī)則與類(lèi)一樣采用大駝峰命名法莽鸭,多以able或ible結(jié)尾,如
interface Runnable ;
interface Accessible吃靠。
注意:
如果項(xiàng)目采用MVP,所有Model足淆、View巢块、Presenter的接口都以I為前綴礁阁,不加后綴,其他的接口采用上述命名規(guī)則族奢。
方法名
方法名都以小駝峰命名法 (LowerCamelCase) 風(fēng)格編寫(xiě)姥闭。
方法名通常是動(dòng)詞或動(dòng)詞短語(yǔ)。
方法 | 說(shuō)明 |
---|---|
initXX() | 初始化相關(guān)方法,使用init為前綴標(biāo)識(shí)越走,如初始化布局initView() |
isXX() checkXX() | 方法返回值為boolean型的請(qǐng)使用is或check為前綴標(biāo)識(shí) |
getXX() | 返回某個(gè)值的方法棚品,使用get為前綴標(biāo)識(shí) |
handleXX() | 對(duì)數(shù)據(jù)進(jìn)行處理的方法,盡量使用handle為前綴標(biāo)識(shí) |
displayXX()/showXX() | 彈出提示框和提示信息廊敌,使用display/show為前綴標(biāo)識(shí) |
saveXX() | 與保存數(shù)據(jù)相關(guān)的铜跑,使用save為前綴標(biāo)識(shí) |
resetXX() | 對(duì)數(shù)據(jù)重組的,使用reset前綴標(biāo)識(shí) |
clearXX() | 清除數(shù)據(jù)相關(guān)的 |
removeXXX() | 清除數(shù)據(jù)相關(guān)的 |
drawXXX() | 繪制數(shù)據(jù)或效果相關(guān)的骡澈,使用draw前綴標(biāo)識(shí) |
下劃線可能出現(xiàn)在JUnit測(cè)試方法名稱(chēng)中用以分隔名稱(chēng)的邏輯組件锅纺。一個(gè)典型的模式是:test_,例如:testPop_emptyStack肋殴。
并不存在唯一正確的方式來(lái)命名測(cè)試方法囤锉。
常量名
常量名都以下劃線命名法風(fēng)格編寫(xiě)。模式為CONSTANT_CASE护锤,全部字母大寫(xiě)官地,用下劃線分隔單詞。
每個(gè)常量都是一個(gè)靜態(tài)final字段烙懦,但不是所有靜態(tài)final字段都是常量区丑。在決定一個(gè)字段是否是一個(gè)常量時(shí),考慮它是否真的感覺(jué)像是一個(gè)常量修陡。
例如沧侥,如果任何一個(gè)該實(shí)例的觀測(cè)狀態(tài)是可變的,則它幾乎肯定不會(huì)是一個(gè)常量魄鸦。只是永遠(yuǎn)不打算改變對(duì)象一般是不夠的宴杀,它要真的一直不變才能將它示為常量。
非常量字段名
非常量字段名以小駝峰命名法 (LowerCamelCase) 風(fēng)格的基礎(chǔ)上改造為如下風(fēng)格:
基本結(jié)構(gòu)為scopeVariableNameType拾因,
scope:范圍
非公有旺罢,非靜態(tài)字段命名以m開(kāi)頭。
靜態(tài)字段命名以s開(kāi)頭绢记。
公有非靜態(tài)字段命名以p開(kāi)頭扁达。
公有靜態(tài)字段(全局變量)命名以g開(kāi)頭。
public static final 字段(常量) 全部大寫(xiě)蠢熄,并用下劃線連起來(lái)跪解。
例子:
public class MyClass {
public static final int SOME_CONSTANT = 42;
public int pField;
private static MyClass sSingleton;
int mPackagePrivate;
private int mPrivate;
protected int mProtected;
public static int gField;
}
使用1字符前綴來(lái)表示作用范圍,1個(gè)字符的前綴必須小寫(xiě)签孔,前綴后面是由表意性強(qiáng)的一個(gè)單詞或多個(gè)單詞組成的名字叉讥,而且每個(gè)單詞的首寫(xiě)字母大寫(xiě)窘行,其它字母小寫(xiě),這樣保證了對(duì)變量名能夠進(jìn)行正確的斷句图仓。
Type:類(lèi)型
考慮到Android中使用很多UI控件罐盔,為避免控件和普通成員變量混淆以及更好達(dá)意,所有用來(lái)表示控件的成員變量統(tǒng)一加上控件縮寫(xiě)作為后綴(文末附有縮寫(xiě)表)救崔。
對(duì)于普通變量一般不添加類(lèi)型后綴惶看,如果統(tǒng)一添加類(lèi)型后綴,請(qǐng)參考文末的縮寫(xiě)表六孵。
用統(tǒng)一的量詞通過(guò)在結(jié)尾處放置一個(gè)量詞纬黎,就可創(chuàng)建更加統(tǒng)一的變量,它們更容易理解狸臣,也更容易搜索莹桅。
注意:如果項(xiàng)目中使用ButterKnife,則不添加m前綴烛亦,以LowerCamelCase風(fēng)格命名诈泼。
例如,請(qǐng)使用 mCustomerStrFirst 和 mCustomerStrLast煤禽,而不要使用mFirstCustomerStr和mLastCustomerStr铐达。
量詞列表:量詞后綴說(shuō)明
First 一組變量中的第一個(gè)
Last 一組變量中的最后一個(gè)
Next 一組變量中的下一個(gè)變量
Prev 一組變量中的上一個(gè)
Cur 一組變量中的當(dāng)前變量。
說(shuō)明:
集合添加如下后綴:List檬果、Map瓮孙、Set
數(shù)組添加如下后綴:Arr
注意:所有的VO(值對(duì)象)統(tǒng)一采用標(biāo)準(zhǔn)的lowerCamelCase風(fēng)格編寫(xiě),所有的DTO(數(shù)據(jù)傳輸對(duì)象)就按照接口文檔中定義的字段名編寫(xiě)选脊。
參數(shù)名
參數(shù)名以LowerCamelCase風(fēng)格編寫(xiě)
局部變量名
局部變量名以LowerCamelCase風(fēng)格編寫(xiě)杭抠,比起其它類(lèi)型的名稱(chēng),局部變量名可以有更為寬松的縮寫(xiě)恳啥。
雖然縮寫(xiě)更寬松偏灿,但還是要避免用單字符進(jìn)行命名,除了臨時(shí)變量和循環(huán)變量钝的。
即使局部變量是final和不可改變的翁垂,也不應(yīng)該把它示為常量,自然也不能用常量的規(guī)則去命名它硝桩。
臨時(shí)變量
臨時(shí)變量通常被取名為i沿猜,j,k碗脊,m和n啼肩,它們一般用于整型;c,d疟游,e呼畸,它們一般用于字符型痕支。 如: for (int i = 0; i < len ; i++)颁虐,并且它和第一個(gè)單詞間沒(méi)有空格。
類(lèi)型變量名
類(lèi)型變量可用以下兩種風(fēng)格之一進(jìn)行命名:
單個(gè)的大寫(xiě)字母卧须,后面可以跟一個(gè)數(shù)字(如:E, T, X, T2)另绩。
以類(lèi)命名方式,后面加個(gè)大寫(xiě)的T(如:RequestT, FooBarT)花嘶。
資源文件命名規(guī)范
布局文件(XML文件(layout布局文件)):
全部小寫(xiě)笋籽,采用下劃線命名法:
contentview 命名
必須以全部單詞小寫(xiě),單詞間以下劃線分割椭员,使用名詞或名詞詞組车海。
所有Activity或Fragment的contentView必須與其類(lèi)名對(duì)應(yīng),對(duì)應(yīng)規(guī)則為:
將所有字母都轉(zhuǎn)為小寫(xiě)隘击,將類(lèi)型和功能調(diào)換(也就是后綴變前綴)侍芝。
例如:activity_main.xmlDialog命名:
dialog_描述.xml
例如:dialog_hint.xmlPopupWindow命名:
ppw_描述.xml
例如:ppw_info.xml列表項(xiàng)命名:
item_描述.xml
例如:item_city.xml包含項(xiàng)命名:
模塊_(位置)描述.xml
例如:activity_main_head.xml、activity_main_bottom.xml
注意:通用的包含項(xiàng)命名采用:項(xiàng)目名稱(chēng)縮寫(xiě)_描述.xml
例如:xxxx_title.xml
圖片文件(圖片mipmap/drawable文件夾下):
全部小寫(xiě)埋同,采用下劃線命名法州叠,加前綴區(qū)分
命名模式:可加后綴 _small 表示小圖, _big 表示大圖,邏輯名稱(chēng)可由多個(gè)單詞加下劃線組成凶赁,采用以下規(guī)則:
用途_模塊名_邏輯名稱(chēng)
用途_模塊名_顏色
用途_邏輯名稱(chēng)
用途_顏色
說(shuō)明:用途也指控件類(lèi)型(具體見(jiàn)UI控件縮寫(xiě)表)
例如:
btn_main_home.png
按鍵
divider_maket_white.png
分割線
ic_edit.png
圖標(biāo)
bg_main.png
背景
btn_red.png
紅色按鍵
btn_red_big.png
紅色大按鍵
ic_head_small.png
小頭像
bg_input.png
輸入框背景
divider_white.png
白色分割線
如果有多種形態(tài)如按鈕等除外如 btn_xx.xml(selector)
名稱(chēng) | 功能 |
---|---|
btn_xx | 按鈕圖片使用btn_整體效果(selector) |
btn_xx_normal | 按鈕圖片使用btn_正常情況效果 |
btn_xx_pressed | 按鈕圖片使用btn_點(diǎn)擊時(shí)候效果 |
btn_xx_focused | state_focused聚焦效果 |
btn_xx_disabled | state_enabled (false)不可用效果 |
btn_xx_checked | state_checked選中效果 |
btn_xx_selected | state_selected選中效果 |
btn_xx_hovered | state_hovered懸停效果 |
btn_xx_checkable | state_checkable可選效果 |
btn_xx_activated | state_activated激活的 |
btn_xx_windowfocused | state_window_focused |
bg_head | 背景圖片使用bg_功能_說(shuō)明 |
def_search_cell | 默認(rèn)圖片使用def_功能_說(shuō)明 |
ic_more_help | 圖標(biāo)圖片使用ic_功能_說(shuō)明 |
seg_list_line | 具有分隔特征的圖片使用seg_功能_說(shuō)明 |
sel_ok | 選擇圖標(biāo)使用sel_功能_說(shuō)明 |
注意:
使用AndroidStudio的插件SelectorChapek可以快速生成selector咧栗,前提是命名要規(guī)范。
動(dòng)畫(huà)文件(anim文件夾下):
全部小寫(xiě)虱肄,采用下劃線命名法致板,加前綴區(qū)分。
具體動(dòng)畫(huà)采用以下規(guī)則:
模塊名_邏輯名稱(chēng)
邏輯名稱(chēng):
refresh_progress.xml
market_cart_add.xml
market_cart_remove.xml
普通的tween動(dòng)畫(huà)采用如下表格中的命名方式
// 前面為動(dòng)畫(huà)的類(lèi)型咏窿,后面為方向
動(dòng)畫(huà)命名例子 | 規(guī)范寫(xiě)法 |
---|---|
fade_in | 淡入 |
fade_out | 淡出 |
push_down_in | 從下方推入 |
push_down_out | 從下方推出 |
push_left | 推向左方 |
slide_in_from_top | 從頭部滑動(dòng)進(jìn)入 |
zoom_enter | 變形進(jìn)入 |
slide_in | 滑動(dòng)進(jìn)入 |
shrink_to_middle | 中間縮小 |
values中name命名
類(lèi)別 | 命名 | 示例 |
---|---|---|
strings | strings的name命名使用下劃線命名法斟或, 采用以下規(guī)則:模塊名+邏輯名稱(chēng) |
main_menu_about 主菜單按鍵文字 friend_title 好友模塊標(biāo)題欄 friend_dialog_del 好友刪除提示 login_check_email 登錄驗(yàn)證 dialog_title 彈出框標(biāo)題 button_ok 確認(rèn)鍵 loading 加載文字 |
colors | colors的name命名使用下劃線命名法, 采用以下規(guī)則:模塊名+邏輯名稱(chēng) |
顏色 friend_info_bg friend_bg transparent gray |
styles | styles的name命名使用 Camel命名法翰灾, 采用以下規(guī)則:模塊名+邏輯名稱(chēng) |
main_tabBottom |
layout中的id命名
命名模式為:view縮寫(xiě)_view的邏輯名稱(chēng)
在Activity中的變量命名使用 view 縮寫(xiě)做后綴缕粹,如:mUserNameTV(展示用戶(hù)名的TextView)
編程實(shí)踐
@Override:能用則用
只要是合法的,就把@Override注解給用上纸淮。
捕獲的異常:不能忽視
除了下面的例子平斩,對(duì)捕獲的異常不做響應(yīng)是極少正確的。(典型的響應(yīng)方式是打印日志咽块,或者如果它被認(rèn)為是不可能的绘面,則把它當(dāng)作一個(gè) AssertionError 重新拋出。)
如果它確實(shí)是不需要在catch塊中做任何響應(yīng),需要做注釋加以說(shuō)明(如下面的例子)揭璃。
try {
int i = Integer.parseInt(response);
return handleNumericResponse();
} catch (NumberFormatException ok) {
// it's not numeric; that's fine, just continue
}
return handleTextResponse(response);
例外:在測(cè)試中晚凿,如果一個(gè)捕獲的異常被命名為expected,則它可以被不加注釋地忽略瘦馍。下面是一種非常常見(jiàn)的情形歼秽,用以確保所測(cè)試的方法會(huì)拋出一個(gè)期望中的異常,因此在這里就沒(méi)有必要加注釋情组。
try {
emptyStack.pop();
fail();
} catch (NoSuchElementException expected) {
}
捕獲具體的異常燥筷,不要直接捕獲Exception
try {
emptyStack.pop();
fail();
} catch (NoSuchElementException expected) { //good
//} catch (Exception expected) { //bad
}
靜態(tài)成員:使用類(lèi)進(jìn)行調(diào)用
使用類(lèi)名調(diào)用靜態(tài)的類(lèi)成員,而不是具體某個(gè)對(duì)象或表達(dá)式院崇。
Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad
Javadoc
格式
一般形式
Javadoc塊的基本格式如下所示:
/**
* Multiple lines of Javadoc text are written here,
* wrapped normally...
* @param str String Value
* @return A Int Value
* @throws ...
* @deprecated ...
* @see ...
* {@link包.類(lèi)#成員 標(biāo)簽}
*/
public int method(String str) { ... }
或者是以下單行形式:
/** An especially short bit of Javadoc. */
基本格式總是OK的肆氓。當(dāng)整個(gè)Javadoc塊能容納于一行時(shí)(且沒(méi)有Javadoc標(biāo)記@XXX),可以使用單行形式底瓣。
段落
空行(即谢揪,只包含最左側(cè)星號(hào)的行)會(huì)出現(xiàn)在段落之間和Javadoc標(biāo)記(@XXX)之前(如果有的話)。
除了第一個(gè)段落捐凭,每個(gè)段落第一個(gè)單詞前都有標(biāo)簽拨扶,并且它和第一個(gè)單詞間沒(méi)有空格。
Javadoc標(biāo)記
標(biāo)準(zhǔn)的Javadoc標(biāo)記按以下順序出現(xiàn):@param, @return, @throws, @deprecated,
前面這4種標(biāo)記如果出現(xiàn)柑营,描述都不能為空屈雄。 當(dāng)描述無(wú)法在一行中容納,連續(xù)行需要至少再縮進(jìn)4個(gè)空格官套。
摘要片段
每個(gè)類(lèi)或成員的Javadoc以一個(gè)簡(jiǎn)短的摘要片段開(kāi)始酒奶。這個(gè)片段是非常重要的,在某些情況下奶赔,它是唯一出現(xiàn)的文本惋嚎,比如在類(lèi)和方法索引中。
這只是一個(gè)小片段站刑,可以是一個(gè)名詞短語(yǔ)或動(dòng)詞短語(yǔ)邻薯,但不是一個(gè)完整的句子春感。它不會(huì)以A {@code Foo} is a…或This method returns…開(kāi)頭,它也不會(huì)是一個(gè)完整的祈使句岗照,如Save the record…多艇。然而,由于開(kāi)頭大寫(xiě)及被加了標(biāo)點(diǎn)因悲,它看起來(lái)就像是個(gè)完整的句子堕汞。
注意:
一個(gè)常見(jiàn)的錯(cuò)誤是把簡(jiǎn)單的Javadoc寫(xiě)成
/** @return the customer ID */,這是不正確的晃琳。它應(yīng)該寫(xiě)成/** Returns the customer ID. */讯检。
哪里需要使用Javadoc
至少在每個(gè)public類(lèi)及它的每個(gè)public和protected成員處使用Javadoc琐鲁,以下是一些例外:
例外:不言自明的方法
對(duì)于簡(jiǎn)單明顯的方法如getFoo,Javadoc是可選的(即人灼,是可以不寫(xiě)的)围段。這種情況下除了寫(xiě)”Returns the foo”,確實(shí)也沒(méi)有什么值得寫(xiě)了投放。
單元測(cè)試類(lèi)中的測(cè)試方法可能是不言自明的最常見(jiàn)例子了奈泪,我們通常可以從這些方法的描述性命名中知道它是干什么的跪呈,因此不需要額外的文檔說(shuō)明段磨。
注意:
如果有一些相關(guān)信息是需要讀者了解的取逾,那么以上的例外不應(yīng)作為忽視這些信息的理由耗绿。例如,對(duì)于方法名getCanonicalName砾隅,
就不應(yīng)該忽視文檔說(shuō)明误阻,因?yàn)樽x者很可能不知道詞語(yǔ)canonical name指的是什么。
例外:重載
如果一個(gè)方法重載了超類(lèi)中的方法晴埂,那么Javadoc并非必需的究反。
可選的Javadoc
對(duì)于包外不可見(jiàn)的類(lèi)和方法,如有需要儒洛,也是要使用Javadoc的精耐。如果一個(gè)注釋是用來(lái)定義一個(gè)類(lèi),方法琅锻,字段的整體目的或行為卦停,那么這個(gè)注釋?xiě)?yīng)該寫(xiě)成Javadoc,這樣更統(tǒng)一更友好恼蓬。
UI控件縮寫(xiě)表
控件 | 縮寫(xiě) | 例子 |
---|---|---|
LinearLayout | ll | mFriendLL |
RelativeLayout | rl | mMessageRL |
FrameLayout | fl | mCartFL |
TableLayout | tl | mTabTL |
Button | btn | mHomeBtn |
ImageButton | ibtn | mPlayIBtn |
TextView | tv | mNameTV |
EditText | et | mNameET |
ListView | lv | mCartLV |
ImageView | iv | mHeadIV |
GridView | gv | mPhotoGV |
常見(jiàn)的英文單詞縮寫(xiě)
名稱(chēng) | 縮寫(xiě) |
---|---|
icon | ic (主要用在app的圖標(biāo)) |
color | cl(主要用于顏色值) |
divider | di(主要用于分隔線惊完,不僅包括Listview中的divider,還包括普通布局中的線) |
selector | sl(主要用于某一view多種狀態(tài)处硬,不僅包括Listview中的selector小槐,還包括按鈕的selector) |
average | avg |
background | bg(主要用于布局和子布局的背景) |
buffer | buf |
control | ctrl |
delete | del |
document | doc |
error | err |
escape | esc |
increment | inc |
infomation | info |
initial | init |
image | img |
Internationalization | I18N |
length | len |
library | lib |
message | msg |
password | pwd |
position | pos |
server | srv |
string | str |
temp | tmp |
window | win |
程序中使用單詞縮寫(xiě)原則:不要用縮寫(xiě),除非該縮寫(xiě)是約定俗成的荷辕。