1 介紹
這份文檔是Google Java編程風(fēng)格規(guī)范的完整定義列另。當(dāng)且僅當(dāng)一個Java源文件符合此文檔中的規(guī)則, 我們才認(rèn)為它符合Google的Java編程風(fēng)格往弓。
與其它的編程風(fēng)格指南一樣疏唾,這里所討論的不僅僅是編碼格式美不美觀的問題, 同時(shí)也討論一些約定及編碼標(biāo)準(zhǔn)函似。然而槐脏,這份文檔主要側(cè)重于我們所普遍遵循的規(guī)則, 對于那些不是明確強(qiáng)制要求的撇寞,我們盡量避免提供意見顿天。
1.1 術(shù)語說明
本文檔除非特殊說明:
- class(類): 統(tǒng)指普通的
class
類型、enum
枚舉類型蔑担、interface
類型和annotation
類型露氮。 - comment(注釋): 總是指implementation comments(實(shí)現(xiàn)注釋,
/* */
)钟沛。我們不使用“文檔注釋”這樣的說法,而會直接說Javadoc
局扶。
其他術(shù)語說明恨统,將在文檔中需要說明的地方單獨(dú)說明叁扫。
1.2 文檔說明
本文檔中的代碼并不一定符合所有規(guī)范。即使這些代碼遵循Google Style, 但這不是唯一的代碼規(guī)范畜埋。例子中可選的格式風(fēng)格也不應(yīng)該作為強(qiáng)制執(zhí)行的規(guī)范莫绣。
2 源碼文件基礎(chǔ)
2.1 文件名
源碼文件名由它所包含的頂級class的類名(大小寫敏感), 加上.java
后綴組成.
2.2 文件編碼:UTF-8
源碼文件使用UTF-8
編碼。
2.3 特殊字符
2.3.1 空格字符
除了換行符外悠鞍,ASCII水平空白字符(0x20)
是源碼文件中唯一支持的空格字符对室。這意味著:
- 其他空白字符將被轉(zhuǎn)義。
- Tab字符不被用作縮進(jìn)控制咖祭。
2.3.2 特殊轉(zhuǎn)義字符串
任何需要轉(zhuǎn)義字符串表示的字符(例如\b
, \t
, \n
, \f
, \r
, \'
, \\
等)掩宜,采用這種轉(zhuǎn)義字符串的方式表示,而不采用對應(yīng)字符的八進(jìn)制數(shù)(例如: \012
)或Unicode碼(例如 \u000a
)表示么翰。
2.3.3 非ASCII字符
對于其余非ASCII字符牺汤,直接使用Unicode字符(例如 ∞
),或者使用對應(yīng)的Unicode碼(例如 \u221e
)轉(zhuǎn)義浩嫌,都是允許的檐迟。唯一需要考慮的是,何種方式更能使代碼容易閱讀和理解码耐。
注意:在使用unicode碼轉(zhuǎn)義追迟,或者甚至是有時(shí)直接使用unicode字符的時(shí)候,添加一點(diǎn)說明注釋將對別人讀懂代碼很有幫助骚腥。
例子:
Example | Discussion |
---|---|
String unitAbbrev = "μs"; | 贊敦间,即使沒有注釋也非常清晰 |
String unitAbbrev = "\u03bcs"; // "μs" | 允許,但沒有理由要這樣做 |
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" | 允許桦沉,但這樣做顯得笨拙還容易出錯 |
String unitAbbrev = "\u03bcs"; | 很糟每瞒,讀者根本看不出這是什么 |
return '\ufeff' + content; // byte order mark | Good,對于非打印字符纯露,使用轉(zhuǎn)義剿骨,并在必要時(shí)寫上注釋 |
注意:永遠(yuǎn)不要由于害怕某些程序可能無法正確處理非ASCII字符而讓你的代碼可讀性變差。如果出現(xiàn)這樣的問題埠褪,應(yīng)該由出現(xiàn)問題的程序去解決浓利。
3 源碼文件結(jié)構(gòu)
源碼文件按照先后順序,由以下幾部分組成:
- License或者copyright聲明信息钞速。(如果需要聲明)
- 包聲明語句贷掖。
- import語句。
- class類聲明(每個源碼文件只能有唯一一個頂級class)渴语。
每個部分之間應(yīng)該只有一行空行
作為間隔苹威。
3.1 License 或者 copyright的聲明信息。
如果需要聲明license或copyright信息驾凶,應(yīng)該在文件開始時(shí)聲明牙甫。
3.2 包聲明
包聲明的行掷酗,沒有行長度的限制。單行長度限制(4.4部分有詳細(xì)說明窟哺,80或100)不適用于包聲明泻轰。
3.3 Import語句
3.3.1 不使用通配符import
不應(yīng)該使用通配符import
,不管是否是靜態(tài)導(dǎo)入且轨。
3.3.2 沒有行長度限制
import語句的行浮声,沒有行長度的限制
。單行長度限制(4.4部分有詳細(xì)說明旋奢,80或100)不適用于import語句所在行泳挥。
3.3.3 順序和空行
import語句應(yīng)該被分為幾個組,每個組之間由單行的空行隔開黄绩。分組的順序如下:
- 所有的static import為歸為一組羡洁。
-
com.google
包的import歸為一組。 - 使用的第三方包的引用爽丹。每個頂級第三方包歸為一組筑煮。第三方包之間按ASCII碼排序。例如:
android
,com
,junit
,org
,sun
-
java
包歸為一組粤蝎。 -
javax
包歸為一組真仲。
同一組內(nèi)的import語句之間不應(yīng)用空行隔開。同一組中的import語句按ASCII碼排序初澎。
3.4 類聲明
3.4.1 只聲明唯一一個頂級class
每個源碼文件中只能有一個頂級class秸应。package-info.java文件除外。
3.4.2 類成員順序
類成員的順序?qū)Υa的易讀性有很大影響碑宴,但是沒有一個統(tǒng)一正確的標(biāo)準(zhǔn)软啼。不同的類可能有不同的排序方式。
重要的是延柠,每個class都要按照一定的邏輯規(guī)律排序
祸挪。當(dāng)被問及時(shí),能夠解釋清楚為什么這樣排序贞间。例如贿条,新增加的成員方法,不是簡單地放在class代碼最后面增热,按日期排序不是按邏輯排序整以。
3.4.2.1 重載方法:不應(yīng)該分開
當(dāng)一個類有多個構(gòu)造函數(shù),或者多個同名成員方法時(shí)峻仇,這些函數(shù)應(yīng)該寫在一起公黑,不應(yīng)該被其他成員分開。
4 格式
術(shù)語說明:塊狀結(jié)構(gòu)(block-like construct)指類、成員函數(shù)和構(gòu)造函數(shù)的實(shí)現(xiàn)部分(花括號中間部分)帆调。注意奠骄,在后面的4.8.3.1節(jié)中講到數(shù)組初始化,所有的數(shù)組初始化都可以被認(rèn)為是一個塊狀結(jié)構(gòu)(非強(qiáng)制)番刊。
4.1 花括號
4.1.1 花括號在需要的地方使用
花括號一般用在if
, else
, for
, do
, 和 while
等語句。甚至當(dāng)它的實(shí)現(xiàn)為空或者只有一句話時(shí)影锈,也需要使用芹务。
4.1.2 非空語句塊采用K&R風(fēng)格
對于非空語句塊,花括號遵循K&R風(fēng)格:
- 左括號前不換行鸭廷。
- 左括號后換行枣抱。
- 右括號前換行。
- 如果右括號結(jié)束一個語句塊或者函數(shù)體辆床、構(gòu)造函數(shù)體或者有命名的類體佳晶,則需要換行。例如讼载,當(dāng)右括號后面接
else
或者逗號時(shí)轿秧,不應(yīng)該換行。
例子:
return new MyClass() {
@Override public void method() {
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
}
}
};
一些例外的情況咨堤,將在4.8.1節(jié)講枚舉類型的時(shí)候講到菇篡。
4.1.3 空語句塊:使代碼更簡潔
一個空的語句塊,可以在左花括號之后直接接右花括號一喘,中間不需要空格或換行驱还。但是當(dāng)一個由幾個語句塊聯(lián)合組成的語句塊時(shí),則需要換行凸克。(例如:if/else-if/else
or try/catch/finally
).
例子:
void doNothing () {}
4.2 語句塊的縮進(jìn):2空格
每當(dāng)一個新的語句塊產(chǎn)生议蟆,縮進(jìn)就增加兩個空格。當(dāng)這個語句塊結(jié)束時(shí)萎战,縮進(jìn)恢復(fù)到上一層級的縮進(jìn)格數(shù)咐容。縮進(jìn)要求對整個語句塊中的代碼和注釋都適用撞鹉。(例子可參考之前4.1.2節(jié)非空語句塊采用K&R風(fēng)格)疟丙。
4.3 一行一個語句
每個語句后要換行
4.4 行長度限制:80或100
不同的項(xiàng)目可以選擇采用80個字符或者100個字符作為限制。除了以下幾個特殊情況外鸟雏,其他代碼內(nèi)容都需要遵守這個長度限制享郊。這在4.5節(jié)長行斷行會有詳細(xì)解釋。
例外:
- 按照行長度限制孝鹊,無法實(shí)現(xiàn)地方(例如:javadoc中超長的URL地址炊琉, 或者一個超長的JSNI方法的引用);
-
package
和import
語句不受長度限制。(見3.2包聲明苔咪、3.3節(jié)Import語句)锰悼; - 注釋中的命令行指令行,將被直接復(fù)制到shell中執(zhí)行的团赏。
4.5 長行斷行
術(shù)語說明: 當(dāng)一行代碼按照其他規(guī)范都合法箕般,只是為了避免超出行長度限制而換行時(shí),稱為長行斷行舔清。
長行斷行丝里,沒有一個適合所有場景的全面、確定的規(guī)范体谒。但很多相同的情況杯聚,我們經(jīng)常使用一些行之有效的斷行方法。
注意:將長行封裝為函數(shù)抒痒,或者使用局部變量的方法幌绍,也可以解決一些超出行長度限制的情況。并非一定要斷行故响。
4.5.1 在何處斷行
斷行的主要原則是:選擇在更高一級的語法邏輯
的地方斷行傀广。其他一些原則如下:
- 如果在
非賦值運(yùn)算符
處斷開,那么在該符號前斷開(比如+被去,它將位于下一行)主儡。
注意: 這一點(diǎn)與Google其它語言的編程風(fēng)格不同(如C++和JavaScript)。 這條規(guī)則也適用于以下“類運(yùn)算符”符號:點(diǎn)分隔符(.
)惨缆,類型界限中的&(<T extends Foo & Bar>
)糜值,catch塊中的管道符號(catch (FooException | BarException e
) - 如果在
賦值運(yùn)算符
處斷開,通常的做法是在該符號后斷開(比如=坯墨,它與前面的內(nèi)容留在同一行)寂汇。這條規(guī)則也適用于foreach
語句中的分號。 - 方法名或構(gòu)造函數(shù)名與左括號留在同一行捣染。
- 逗號(
,
)與其前面的內(nèi)容留在同一行骄瓣。
4.5.2 斷行的縮進(jìn):至少4個字符
當(dāng)斷行之后,在第一行之后的行耍攘,我們叫做延續(xù)行榕栏。每一個延續(xù)行在第一行的基礎(chǔ)上至少縮進(jìn)四個字符。
當(dāng)原行之后有多個延續(xù)行的情況蕾各,縮進(jìn)可以大于4個字符扒磁。如果多個延續(xù)行之間由同樣的語法元素?cái)嘈校鼈兛梢圆捎孟嗤目s進(jìn)式曲。
第4.6.3節(jié)介紹水平對齊中妨托,解決了使用多個空格與之前行縮進(jìn)對齊的問題缸榛。
4.6 空白空間
4.6.1 垂直空白
單行空行在以下情況使用:
- 類成員間需要空行隔開:例如:
成員變量
、構(gòu)造函數(shù)
兰伤、成員函數(shù)
内颗、內(nèi)部類
、靜態(tài)初始化語句塊(static initializers)
敦腔、實(shí)例初始化語句塊(instance initializers)
均澳。
例外:成員變量之間的空白行不是必需的。一般多個成員變量中間的空行符衔,是為了對成員變量做邏輯上的分組负懦。 - 在函數(shù)內(nèi)部,根據(jù)代碼邏輯分組的需要柏腻,設(shè)置空白行作為間隔。
- 類的第一個成員之前系吭,或者最后一個成員結(jié)束之后五嫂,用空行間隔。(可選)
- 本文檔中其他部分介紹的需要空行的情況肯尺。(例如 3.3節(jié)中的import語句)
單空行時(shí)使用多行空行是允許的沃缘,但是不要求也不鼓勵。
4.6.2 水平空白
除了語法则吟、其他規(guī)則槐臀、詞語分隔、注釋和javadoc外氓仲,水平的ASCII空格只在以下情況出現(xiàn):
- 所有保留的關(guān)鍵字與緊接它之后的位于同一行的左括號之間需要用空格隔開水慨。(例如
if
、for
敬扛、catch
) - 所有保留的關(guān)鍵字與在它之前的右花括號之間需要空格隔開晰洒。(例如
else
、catch
) - 在左花括號之前都需要空格隔開啥箭。只有兩種例外:
@SomeAnnotation({a, b})
谍珊、String [][] x = {{"foo"}};
- 所有的二元運(yùn)算符和三元運(yùn)算符的兩邊,都需要空格隔開急侥。
- 逗號砌滞、冒號、分號和右括號之后坏怪,需要空格隔開贝润。
-
//
雙斜線開始一行注釋時(shí)。雙斜線兩邊都應(yīng)該用空格隔開陕悬。并且可使用多個空格题暖,但是不做強(qiáng)制要求。 - 變量聲明時(shí),變量類型和變量名之間需要用空格隔開胧卤。
- 初始化一個數(shù)組時(shí)唯绍,花括號之間可以用空格隔開,也可以不使用枝誊。(例如:
new int[] {5, 6}
和new int[] { 5, 6 }
都可以)
注意:這一原則不影響一行開始或者結(jié)束時(shí)的空格况芒。只針對行內(nèi)部字符之間的隔開。
4.6.3 水平對齊:不做強(qiáng)制要求
術(shù)語說明: 水平對齊叶撒,是指通過添加多個空格绝骚,使本行的某一符號與上一行的某一符號上下對齊。
這種對齊是被允許的祠够,但是不會做強(qiáng)制要求压汪。
以下是沒有水平對齊和水平對齊的例子;
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
注意:水平對齊能夠增加代碼的可讀性,但是增加了未來維護(hù)代碼的難度古瓤≈蛊剩考慮到維護(hù)時(shí)只需要改變一行代碼,之前的對齊可以不需要改動落君。為了對齊穿香,你更有可能改了一行代碼,同時(shí)需要更改附近的好幾行代碼绎速,而這幾行代碼的改動皮获,可能又會引起一些為了保持對齊的代碼改動。那原本這行改動纹冤,我們稱之為“爆炸半徑”洒宝。這種改動,在最壞的情況下可能會導(dǎo)致大量的無意義的工作赵哲,即使在最好的情況下待德,也會影響版本歷史信息,減慢代碼review的速度枫夺,引起更多merge代碼沖突的情況将宪。
4.7 分組括號:建議使用
非必須的分組括號只有在編寫代碼者和代碼審核者都認(rèn)為大家不會因?yàn)闆]有它而導(dǎo)致代碼理解錯誤的時(shí)候,或者它不會使代碼更易理解的時(shí)候才能省略橡庞。沒有理由認(rèn)為所有閱讀代碼的人都能記住所有java運(yùn)算符的優(yōu)先級较坛。
4.8 特殊結(jié)構(gòu)
4.8.1 枚舉類型
每個逗號后接一個枚舉變量,不要求換行扒最。
枚舉類型丑勤,如果沒有函數(shù)和javadoc,處理格式是可以按照數(shù)組初始化來處理吧趣。
例子:
private enum Suit { CLUBS , HEARTS , SPADES , DIAMONDS }
枚舉類型也是一種類(Class)法竞,因此Class類的其他格式要求耙厚,也適用于枚舉類型。
4.8.2 變量聲明
4.8.2.1 每次聲明一個變量
不要采用一個聲明岔霸,聲明多個變量薛躬。例如 int a, b
;
4.8.2.2 當(dāng)需要時(shí)才聲明虫溜,盡快完成初始化
局部變量不應(yīng)該習(xí)慣性地放在語句塊的開始處聲明饲化,而應(yīng)該盡量離它第一次使用的地方最近的地方聲明特笋,以減小它們的使用范圍梦湘。
局部變量應(yīng)該在聲明的時(shí)候就進(jìn)行初始化。如果不能在聲明時(shí)初始化翼雀,也應(yīng)該盡快完成初始化徒探。
4.8.3 數(shù)組
4.8.3.1 數(shù)組初始化:可以類似塊代碼處理
所有數(shù)組的初始化葬荷,都可以采用和塊代碼相同的格式處理坑夯。例如以下格式都是允許的:
new int[] {
0, 1, 2, 3
}
new int[] {
0,
1,
2,
3
}
new int[] {
0, 1,
2, 3
}
new int[]
{0, 1, 2, 3}
4.8.3.2 不能像C風(fēng)格一樣聲明數(shù)組
方括號應(yīng)該是變量類型的一部分岖寞,因此不應(yīng)該和變量名放在一起。例如:應(yīng)該是 String [] args
柜蜈,而不是 String args[]
慎璧。
4.8.4 switch語句
術(shù)語說明: switch語句是指在switch花括號中,包含了一組或多組語句塊跨释。每組語句塊都由一個或多個switch標(biāo)簽(例如:case FOO:
或者 default:
)打頭。
4.8.4.1 縮進(jìn)
和其他語句塊一樣厌处,switch花括號之后縮進(jìn)兩個字符鳖谈。
每個switch標(biāo)簽之后,后面緊接的非標(biāo)簽的新行阔涉,按照花括號相同的處理方式縮進(jìn)兩個字符缆娃。在標(biāo)簽結(jié)束后,恢復(fù)到之前的縮進(jìn)瑰排,類似花括號結(jié)束贯要。
4.8.4.2 繼續(xù)向下執(zhí)行的注釋
在switch語句中,每個標(biāo)簽對應(yīng)的代碼執(zhí)行完后椭住,都應(yīng)該通過語句結(jié)束(例如:break
崇渗、continue
、return
或拋出異常)京郑,否則應(yīng)該通過注釋說明宅广,代碼需要繼續(xù)向下執(zhí)行下一個標(biāo)簽的代碼。注釋說明文字只要能說明代碼需要繼續(xù)往下執(zhí)行都可以(通常是 //fall through
)些举。這個注釋在最后一個標(biāo)簽之后不需要注釋跟狱。例如:
switch (input) {
case 1:
case 2:
prepareOneOrTwo();
// fall through
case 3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}
4.8.4.3 default標(biāo)簽需要顯式聲明
每個switch語句中,都需要顯式聲明default
標(biāo)簽户魏。即使沒有任何代碼也需要顯示聲明驶臊。
4.8.5 Annotations
Annotations應(yīng)用到類挪挤、函數(shù)或者構(gòu)造函數(shù)時(shí),應(yīng)緊接javadoc之后关翎。每一行只有一個Annotations扛门。
Annotations所在行不受行長度限制,也不需要增加縮進(jìn)笤休。例如:
@Override
@Nullable
public String getNameIfPresent () { ... }
例外情況:
如果Annotations只有一個尖飞,并且不帶參數(shù)。則它可以和類或方法名放在同一行店雅。例如:
@Override public int hashCode () { ... }
Annotations應(yīng)用到成員變量時(shí)政基,也是緊接javadoc之后。不同的是闹啦,多個annotations可以放在同一行沮明。例如:
@Partial @Mock DataLoader loader ;
對于參數(shù)或者局部變量使用Annotations的情況,沒有特定的規(guī)范窍奋。
4.8.6 注釋
4.8.6.1 語句塊的注釋風(fēng)格
注釋的縮進(jìn)與它所注釋的代碼縮進(jìn)相同荐健。可以采用 /* */
進(jìn)行注釋琳袄,也可以用 //
進(jìn)行注釋江场。當(dāng)使用 /**/
進(jìn)行多行注釋時(shí),每一行都應(yīng)該以 *
開始窖逗, 并且 `* 應(yīng)該上下對齊址否。
例如:
/*
* This is // And so /* Or you can
* okay. // is this. * even do this. */
*/
注意:多行注釋時(shí),如果你希望集成開發(fā)環(huán)境能自動對齊注釋碎紊,你應(yīng)該使用
/**/
佑附,//
一般不會自動對齊。
4.8.7 修飾符
多個類和成員變量的修飾符仗考,按Java Lauguage Specification中介紹的先后順序排序音同。具體是:
public
、protected
秃嗜、private
权均、abstract
、static
锅锨、final
螺句、transient
、volatile
橡类、synchronized
蛇尚、native
和strictfp
5 命名
5.1 適用于所有命名標(biāo)識符的通用規(guī)范
標(biāo)示符只應(yīng)該使用ASCII字母、數(shù)字和下劃線顾画,字母大小寫敏感取劫。因此所有的標(biāo)示符匆笤,都應(yīng)該能匹配正則表達(dá)式 \w+
。
Google Style中谱邪,標(biāo)示符不需要使用特殊的前綴或后綴炮捧,例如: name_
, mName
, s_name
和 kName
。
5.2 不同類型的標(biāo)示符規(guī)范
5.2.1 包名
包名全部用小寫字母惦银,通過 . 將各級連在一起咆课。不應(yīng)該使用下劃線。
5.2.2 類名
類型的命名扯俱,采用以大寫字母開頭的大小寫字符間隔的方式(UpperCamelCase
)书蚪。
class命名一般使用名詞或名詞短語。interface的命名有時(shí)也可以使用形容詞或形容詞短語迅栅。annotation沒有明確固定的規(guī)范殊校。
測試類的命名,應(yīng)該以它所測試的類的名字為開頭读存,并在最后加上Test
結(jié)尾为流。例如:HashTest
、 HashIntegrationTest
让簿。
5.2.3 方法名
方法命名敬察,采用以小寫字母開頭的大小寫字符間隔的方式(lowerCamelCase
)。
方法命名一般使用動詞或者動詞短語尔当。For example:sendMessage
or stop
在JUnit的測試方法中静汤,可以使用下劃線,用來區(qū)分測試邏輯的名字居凶,經(jīng)常使用如下的結(jié)構(gòu):test <MethodUnderTest>_ <state>
。例如:testPop_emptyStack
藤抡,測試方法也可以用其他方式進(jìn)行命名侠碧。
5.2.4 常量名
常量命名,全部使用大寫字符缠黍,詞與詞之間用下劃線隔開弄兜。(CONSTANCE_CASE
)。
常量是一個靜態(tài)成員變量瓷式,但不是所有的靜態(tài)成員變量都是常量替饿。在選擇使用常量命名規(guī)則給變量命名時(shí),你需要明確這個變量是否是常量贸典。例如视卢,如果這個變量的狀態(tài)可以發(fā)生改變,那么這個變量幾乎可以肯定不是常量廊驼。只是計(jì)劃不會發(fā)生改變的變量不足以成為一個常量据过。
下面是常量和非常量的例子:
// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }
// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};
常量一般使用名詞或者名詞短語命名惋砂。
5.2.5 非常量的成員變量名
非常量的成員變量命名(包括靜態(tài)變量和非靜態(tài)變量),采用lowerCamelCase
命名绳锅。
一般使用名詞或名詞短語西饵。
5.2.6 參數(shù)名
參數(shù)命名采用lowerCamelCase
命名。
應(yīng)該避免使用一個字符作為參數(shù)的命名方式鳞芙。
5.2.7 局部變量名
局部變量采用lowerCamelCase
命名眷柔。它相對于其他類型的命名,可以采用更簡短寬松的方式原朝。
但即使如此驯嘱,也應(yīng)該盡量避免采用單個字母進(jìn)行命名的情況,除了在循環(huán)體內(nèi)使用的臨時(shí)變量竿拆。
即使局部變量是final宙拉、不可改變的,它也不能被認(rèn)為是常量丙笋,也不應(yīng)該采用常量的命名方式去命名谢澈。
5.2.8 類型名
類型名有兩種命名方式:
- 單獨(dú)一個大寫字母,有時(shí)后面再跟一個數(shù)字御板。(例如锥忿,
E
、T
怠肋、X
敬鬓、T2
)。 - 像一般的class命名一樣(見5.2.2節(jié))笙各,再在最后接一個大寫字母钉答。(例如,
RequestT
杈抢、FooBarT
)数尿。
5.3 駝峰式命(Camel case) 的定義
有時(shí)一些短語被寫成Camel case的時(shí)候可以有多種寫法。例如一些縮寫詞匯惶楼,或者一些組合詞:IPv6 或者 iOS 等右蹦。
為了統(tǒng)一寫法,Google style給出了一種幾乎可以確定為一種的寫法歼捐。
- 將字符全部轉(zhuǎn)換為ASCII字符何陆,并且去掉 ' 等符號。例如豹储, "Müller's algorithm" 被轉(zhuǎn)換為 "Muellers algorithm" 贷盲。
- 將上一步轉(zhuǎn)換的結(jié)果拆分成一個一個的詞語。從空格處和從其他剩下的標(biāo)點(diǎn)符號處劃分剥扣。
注意:一些已經(jīng)是Camel case的詞語晃洒,也應(yīng)該在這個時(shí)候被拆分慨灭。(例如 AdWords 被拆分為 ad words)。但是例如iOS之類的詞語球及,它其實(shí)不是一個Camel case的詞語氧骤,而是人們慣例使用的一個詞語,因此不用做拆分吃引。
- 經(jīng)過上面兩部后筹陵,先將所有的字母轉(zhuǎn)換為小寫,再把每個詞語的第一個字母轉(zhuǎn)換為大寫镊尺。
- 最后朦佩,將所有詞語連在一起,形成一個標(biāo)示符庐氮。
注意:詞語原來的大小寫規(guī)則语稠,應(yīng)該被完全忽略。
以下是一些例子:
|Prose form|Correct| Incorrect|
|-----|-------|
|"XML HTTP request"| XmlHttpRequest| XMLHTTPRequest|
|"new customer ID"| newCustomerId| newCustomerID|
|"inner stopwatch"| innerStopwatch| innerStopWatch|
|"supports IPv6 on iOS?"| supportsIpv6OnIos| supportsIPv6OnIOS|
|"YouTube importer"| YouTubeImporter YoutubeImporter*| ||
** * **號表示可以接受弄砍,但是不建議使用仙畦。
注意,有些詞語在英文中音婶,可以用 - 連接使用慨畸,也可以不使用 - 直接使用。例如 “nonempty”和 “non-empty”都是可以的衣式。因此寸士,方法名字為
checkNonempty
或者checkNonEmpty
都是可以的。
6 編程實(shí)踐
6.1 @override 都應(yīng)該使用
@override
annotations只要是符合語法的碴卧,都應(yīng)該使用弱卡。
6.2 異常捕獲 不應(yīng)該被忽略
一般情況下,catch住的異常不應(yīng)該被忽略住册,而是都需要做適當(dāng)?shù)奶幚砩舨@鐚㈠e誤日志打印出來,或者如果認(rèn)為這種異常不會發(fā)生界弧,則應(yīng)該作為斷言異常重新拋出。
如果這個catch住的異常確實(shí)不需要任何處理搭综,也應(yīng)該通過注釋做出說明垢箕。例如:
try {
int i = Integer.parseInt(response);
return handleNumericResponse(i);
} catch (NumberFormatException ok) {
// it's not numeric; that's fine, just continue
}
return handleTextResponse(response);
例外:在測試類里,有時(shí)會針對方法是否會拋出指定的異常兑巾,這樣的異常是可以被忽略的条获。但是這個異常通常需要命名為: expected
。例如:
try {
emptyStack.pop();
fail();
} catch (NoSuchElementException expected) {
}
6.3 靜態(tài)成員的訪問:應(yīng)該通過類蒋歌,而不是對象
當(dāng)一個靜態(tài)成員被訪問時(shí)帅掘,應(yīng)該通過class名去訪問委煤,而不應(yīng)該使用這個class的具體實(shí)例對象。例如:
Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad
6.4 不使用Finalizers 方法
重載Object.finalize
方法是非常非常罕見
的修档。
注意:不應(yīng)該使用這以方法碧绞。如果你認(rèn)為你必須使用,請先仔細(xì)閱讀并理解 Effective Java 第七條 “ Avoid Finalizers”吱窝。然后不要使用它讥邻。
7 Javadoc
7.1 格式規(guī)范
7.1.1 通用格式
最基本的javadoc的通用格式如下例:
/**
* Multiple lines of Javadoc text are written here,
* wrapped normally...
*/
public int method(String p1) { ... }
或者為單行格式:
/** An especially short bit of Javadoc. */
通用格式在任何時(shí)候使用都是可以的。當(dāng)javadoc塊只有一行時(shí)院峡,可以使用單行格式來替代通用格式兴使。
7.1.2 段落
空白行:是指javadoc中,上下兩個段落之間只有上下對齊的*
字符的行照激。每個段落的第一行在第一個字符之前发魄,有一個<p>
標(biāo)簽,并且之后不要有任何空格俩垃。
7.1.3 @從句
所有標(biāo)準(zhǔn)的@從句励幼,應(yīng)該按照如下的順序添加:@param
、@return
吆寨、@throws
赏淌、@deprecated
。并且這四種@
從句啄清,不應(yīng)該出現(xiàn)在一個沒有描述的Javadoc塊中六水。
當(dāng)@
從句無法在一行寫完時(shí),應(yīng)該斷行辣卒。延續(xù)行在第一行的@
字符的位置掷贾,縮進(jìn)至少4個字符單位。
7.2 摘要片段
每個類或者成員的javadoc荣茫,都是由一個摘要片段
開始的想帅。這個片段非常重要。因?yàn)樗穷惢蛘叻椒ㄔ谑褂脮r(shí)唯一能看到的文本說明啡莉。
主要摘要只是一個片段港准,應(yīng)該是一個名詞短語或者動詞短語,而不應(yīng)該是一個完整的句子咧欣。但是它應(yīng)該像一個完整的句子一樣使用標(biāo)點(diǎn)符號浅缸。
注意:一種常見的錯誤是以這種形式使用javadoc: */** @return the customer ID / ** .這是不對的。應(yīng)該改為: /**Returns the customer ID. */ ** .
7.3 何處應(yīng)該使用Javadoc
至少魄咕,Javadoc應(yīng)該應(yīng)用于所有的public
類衩椒、public
和protected
的成員變量和方法。和少量例外的情況。
7.3.1 例外:方法本身已經(jīng)足夠說明的情況
當(dāng)方法本身很顯而易見時(shí)毛萌,可以不需要javadoc苟弛。例如:getFoo
。沒有必要加上javadoc說明“Returns the foo”阁将。
單元測試中的方法基本都能通過方法名膏秫,顯而易見地知道方法的作用。因此不需要增加javadoc冀痕。
注意:如果有一些相關(guān)信息是需要讀者了解的荔睹,那么以上的例外不應(yīng)作為忽視這些信息的理由。例如言蛇,對于方法名getCanonicalName僻他,就不應(yīng)該忽視文檔說明,因?yàn)樽x者很可能不知道詞語canonical name 指的是什么 腊尚。當(dāng)大部分代碼閱讀者不知道canonical name是什么意思時(shí)吨拗,不應(yīng)該省略Javadoc, 只能寫** /** Returns the canonical name. */ **。
7.3.2 例外:重載方法
重載方法有時(shí)不需要再寫Javadoc
Google Java Style原文
從Code Review 談如何做技術(shù)
Code Review中的幾個提示