一個統(tǒng)一的編程風格不但能夠增強代碼可讀性,也可以避免許多低級問題杭朱。一個嚴格遵從編碼規(guī)范的團隊阅仔,代碼無論出自多少人之手,都像一個人寫的一樣弧械。本文轉(zhuǎn)載自 小土刀 的博客八酒。
這份文檔是 Google Java 編程風格規(guī)范的完整定義。當且僅當一個 Java 源文件符合此文檔中的規(guī)則刃唐, 我們才認為它符合 Google 的 Java 編程風格羞迷。
與其它的編程風格指南一樣,這里所討論的不僅僅是編碼格式美不美觀的問題画饥, 同時也討論一些約定及編碼標準冒冬。然而磺平,這份文檔主要側(cè)重于我們所普遍遵循的規(guī)則, 對于那些不是明確強制要求的,我們盡量避免提供意見引瀑。
1.1 術(shù)語說明
在本文檔中瘫证,除非另有說明:
- 術(shù)語
class
可表示一個普通類,枚舉類,接口或是annotation
類型(@interface) - 術(shù)語
comment
只用來指代實現(xiàn)的注釋(implementation comments)幅疼,我們不使用documentation comments
一詞,而是用Javadoc
昼接。
其他的術(shù)語說明會偶爾在后面的文檔出現(xiàn)爽篷。
1.2 指南說明
本文檔中的示例代碼并不作為規(guī)范。也就是說慢睡,雖然示例代碼是遵循 Google 編程風格逐工,但并不意味著這是展現(xiàn)這些代碼的唯一方式。 示例中的格式選擇不應(yīng)該被強制定為規(guī)則漂辐。
源文件基礎(chǔ)
2.1 文件名
源文件以其最頂層的類名來命名泪喊,大小寫敏感,文件擴展名為 .java
髓涯。
2.2 文件編碼:UTF-8
源文件編碼格式為 UTF-8
袒啼。
2.3 特殊字符
2.3.1 空白字符
除了行結(jié)束符序列,ASCII 水平空格字符(0x20纬纪,即空格)是源文件中唯一允許出現(xiàn)的空白字符蚓再,這意味著:
- 所有其它字符串中的空白字符都要進行轉(zhuǎn)義。
- 制表符不用于縮進包各。
2.3.2 特殊轉(zhuǎn)義序列
對于具有特殊轉(zhuǎn)義序列的任何字符(\b, \t, \n, \f, \r, ", '
及 \
)摘仅,我們使用它的轉(zhuǎn)義序列,而不是相應(yīng)的八進制(比如 \012
)或 Unicode(比如\u000a
)轉(zhuǎn)義问畅。
2.3.3 非ASCII字符
對于剩余的非 ASCII 字符娃属,是使用實際的 Unicode 字符(比如 ∞
),還是使用等價的 Unicode 轉(zhuǎn)義符(比如 \u221e
)护姆,取決于哪個能讓代碼更易于閱讀和理解矾端。
Tip: 在使用 Unicode 轉(zhuǎn)義符或是一些實際的 Unicode 字符時,建議做些注釋給出解釋签则,這有助于別人閱讀和理解须床。
例如:
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)義,并在必要時寫上注釋
Tip: 大膽去用非ASCII字符膝捞,如果真的有需要的話
源文件結(jié)構(gòu)
一個源文件包含(按順序地):
- 許可證或版權(quán)信息(如有需要)
- package語句
- import語句
- 一個頂級類(只有一個)
以上每個部分之間用一個空行隔開坦刀。
3.1 許可證或版權(quán)信息
如果一個文件包含許可證或版權(quán)信息,那么它應(yīng)當被放在文件最前面。
3.2 package語句
package 語句不換行鲤遥,列限制(4.4節(jié))并不適用于 package 語句沐寺。(即 package 語句寫在一行里)
3.3 import語句
3.3.1 import 不要使用通配符
即,不要出現(xiàn)類似這樣的import語句:import java.util.*;
3.3.2 不要換行
import 語句不換行盖奈,列限制(4.4節(jié))并不適用于 import 語句混坞。(每個 import 語句獨立成行)
3.3.3 順序和間距
import 語句可分為以下幾組,按照這個順序钢坦,每組由一個空行分隔:
- 所有的靜態(tài)導入獨立成組
- com.google imports(僅當這個源文件是在 com.google 包下)
- 第三方的包究孕。每個頂級包為一組,字典序爹凹。例如:
android, com, junit, org, sun
- java imports
- javax imports
組內(nèi)不空行厨诸,按字典序排列。
3.4 類聲明
3.4.1 只有一個頂級類聲明
每個頂級類都在一個與它同名的源文件中(當然禾酱,還包含 .java 后綴)微酬。
例外:package-info.java
,該文件中可沒有 package-info
類颤陶。
3.4.2 類成員順序
類的成員順序?qū)σ讓W性有很大的影響得封,但這也不存在唯一的通用法則。不同的類對成員的排序可能是不同的指郁。最重要的一點,每個類應(yīng)該以某種邏輯去排序它的成員拷呆,維護者應(yīng)該要能解釋這種排序邏輯闲坎。比如,新的方法不能總是習慣性地添加到類的結(jié)尾茬斧,因為這樣就是按時間順序而非某種邏輯來排序的腰懂。
3.4.2.1 重載:永不分離
當一個類有多個構(gòu)造函數(shù),或是多個同名方法项秉,這些函數(shù)/方法應(yīng)該按順序出現(xiàn)在一起绣溜,中間不要放進其它函數(shù)/方法。
格式
術(shù)語說明:塊狀結(jié)構(gòu)(block-like construct)指的是一個類娄蔼,方法或構(gòu)造函數(shù)的主體怖喻。需要注意的是,數(shù)組初始化中的初始值可被選擇性地視為塊狀結(jié)構(gòu)(4.8.3.1節(jié))岁诉。
4.1 大括號
4.1.1 使用大括號(即使是可選的)
大括號與 if, else, for, do, while
語句一起使用锚沸,即使只有一條語句(或是空),也應(yīng)該把大括號寫上涕癣。
4.1.2 非空塊:K & R 風格
對于非空塊和塊狀結(jié)構(gòu)哗蜈,大括號遵循 Kernighan 和 Ritchie
風格 (Egyptian brackets):
- 左大括號前不換行
- 左大括號后換行
- 右大括號前換行
- 如果右大括號是一個語句、函數(shù)體或類的終止,則右大括號后換行; 否則不換行距潘。例如炼列,如果右大括號后面是else或逗號,則不換行音比。
示例:
returnnew MyClass() {
@Overridepublicvoidmethod(){
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
}
}
};
4.8.1 節(jié)給出了enum類的一些例外俭尖。
4.1.3 空塊:可以用簡潔版本
一個空的塊狀結(jié)構(gòu)里什么也不包含,大括號可以簡潔地寫成 {}
硅确,不需要換行目溉。例外:如果它是一個多塊語句的一部分(if/else 或 try/catch/finally) ,即使大括號內(nèi)沒內(nèi)容菱农,右大括號也要換行缭付。
示例:
voiddoNothing(){}
4.2 塊縮進:2個空格
每當開始一個新的塊,縮進增加2個空格循未,當塊結(jié)束時陷猫,縮進返回先前的縮進級別〉难縮進級別適用于代碼和注釋绣檬。(見4.1.2節(jié)中的代碼示例)
4.3 一行一個語句
每個語句后要換行。
4.4 列限制:80 或 100
一個項目可以選擇一行 80 個字符或 100 個字符的列限制嫂粟,除了下述例外娇未,任何一行如果超過這個字符數(shù)限制,必須自動換行星虹。
例外:
- 不可能滿足列限制的行(例如零抬,Javadoc 中的一個長 URL,或是一個長的 JSNI 方法參考)宽涌。
-
package
和import
語句(見3.2節(jié)和3.3節(jié))平夜。 - 注釋中那些可能被剪切并粘貼到
shell
中的命令行。
4.5 自動換行
術(shù)語說明:一般情況下卸亮,一行長代碼為了避免超出列限制(80 或 100 個字符)而被分為多行忽妒,我們稱之為自動換行(line-wrapping)。
我們并沒有全面兼贸,確定性的準則來決定在每一種情況下如何自動換行段直。很多時候,對于同一段代碼會有好幾種有效的自動換行方式寝受。
Tip: 提取方法或局部變量可以在不換行的情況下解決代碼過長的問題(是合理縮短命名長度吧)
4.5.1 從哪里斷開
自動換行的基本準則是:更傾向于在更高的語法級別處斷開坷牛。
- 如果在非賦值運算符處斷開,那么在該符號前斷開(比如 +很澄,它將位于下一行)京闰。注意:這一點與 Google 其它語言的編程風格不同(如 C++ 和 JavaScript)颜及。 這條規(guī)則也適用于以下“類運算符”符號:點分隔符(.),類型界限中的 &(<T extends Foo & Bar>)蹂楣,catch 塊中的管道符號(catch (FooException | BarException e)
- 如果在賦值運算符處斷開俏站,通常的做法是在該符號后斷開(比如 =,它與前面的內(nèi)容留在同一行)痊土。這條規(guī)則也適用于 foreach 語句中的分號肄扎。
- 方法名或構(gòu)造函數(shù)名與左括號留在同一行。
- 逗號(,)與其前面的內(nèi)容留在同一行赁酝。
4.5.2 自動換行時縮進至少+4個空格
自動換行時犯祠,第一行后的每一行至少比第一行多縮進 4 個空格(注意:制表符不用于縮進。見 2.3.1節(jié))酌呆。
當存在連續(xù)自動換行時衡载,縮進可能會多縮進不只 4 個空格(語法元素存在多級時)。一般而言隙袁,兩個連續(xù)行使用相同的縮進當且僅當它們開始于同級語法元素痰娱。
第 4.6.3 水平對齊一節(jié)中指出,不鼓勵使用可變數(shù)目的空格來對齊前面行的符號菩收。
4.6 空白
4.6.1 垂直空白
以下情況需要使用一個空行:
-
類內(nèi)連續(xù)的成員之間:字段梨睁,構(gòu)造函數(shù),方法娜饵,嵌套類坡贺,靜態(tài)初始化塊,實例初始化塊箱舞。
- 例外:兩個連續(xù)字段之間的空行是可選的拴念,用于字段的空行主要用來對字段進行邏輯分組。
在函數(shù)體內(nèi)褐缠,語句的邏輯分組間使用空行。
類內(nèi)的第一個成員前或最后一個成員后的空行是可選的(既不鼓勵也不反對這樣做风瘦,視個人喜好而定)队魏。
要滿足本文檔中其他節(jié)的空行要求(比如3.3節(jié):import 語句)
多個連續(xù)的空行是允許的,但沒有必要這樣做(我們也不鼓勵這樣做)万搔。
4.6.2 水平空白
除了語言需求和其它規(guī)則胡桨,并且除了文字,注釋和 Javadoc 用到單個空格瞬雹,單個 ASCII 空格也出現(xiàn)在以下幾個地方:
分隔任何保留字與緊隨其后的左括號(()(如 if, for, catch 等)昧谊。
分隔任何保留字與其前面的右大括號(})(如 else, catch)。
-
在任何左大括號前({)酗捌,兩個例外:
- @SomeAnnotation({a, b})(不使用空格)呢诬。
- String[][] x = foo;(括號間沒有空格涌哲,見下面的Note)。
-
在任何二元或三元運算符的兩側(cè)尚镰。這也適用于以下“類運算符”符號:
- 類型界限中的
&(<T extends Foo & Bar>)
阀圾。 -
catch
塊中的管道符號(catch (FooException | BarException e)。 -
foreach
語句中的分號狗唉。
- 類型界限中的
在
,, :, ;
及右括號())后如果在一條語句后做注釋初烘,則雙斜杠(//)兩邊都要空格。這里可以允許多個空格分俯,但沒有必要肾筐。
類型和變量之間:
List list
。數(shù)組初始化中缸剪,大括號內(nèi)的空格是可選的吗铐,即
new int[] {5, 6}
和new int[] { 5, 6 }
都是可以的。
Note:這個規(guī)則并不要求或禁止一行的開關(guān)或結(jié)尾需要額外的空格橄登,只對內(nèi)部空格做要求抓歼。
4.6.3 水平對齊:不做要求
術(shù)語說明:水平對齊指的是通過增加可變數(shù)量的空格來使某一行的字符與上一行的相應(yīng)字符對齊。
這是允許的(而且在不少地方可以看到這樣的代碼)拢锹,但Google編程風格對此不做要求谣妻。即使對于已經(jī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
Tip:對齊可增加代碼可讀性,但它為日后的維護帶來問題充坑〖踅考慮未來某個時候,我們需要修改一堆對齊的代碼中的一行捻爷。 這可能導致原本很漂亮的對齊代碼變得錯位辈灼。很可能它會提示你調(diào)整周圍代碼的空白來使這一堆代碼重新水平對齊(比如程序員想保持這種水平對齊的風格), 這就會讓你做許多的無用功也榄,增加了reviewer的工作并且可能導致更多的合并沖突巡莹。
4.7 用小括號來限定組:推薦
除非作者和 reviewer 都認為去掉小括號也不會使代碼被誤解,或是去掉小括號能讓代碼更易于閱讀甜紫,否則我們不應(yīng)該去掉小括號降宅。 我們沒有理由假設(shè)讀者能記住整個 Java 運算符優(yōu)先級表。
4.8 具體結(jié)構(gòu)
4.8.1 枚舉類
枚舉常量間用逗號隔開囚霸,換行可選腰根。
沒有方法和文檔的枚舉類可寫成數(shù)組初始化的格式:
private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }
由于枚舉類也是一個類,因此所有適用于其它類的格式規(guī)則也適用于枚舉類拓型。
4.8.2 變量聲明
4.8.2.1 每次只聲明一個變量
不要使用組合聲明额嘿,比如 int a, b;
瘸恼。
4.8.2.2 需要時才聲明,并盡快進行初始化
不要在一個代碼塊的開頭把局部變量一次性都聲明了(這是 c 語言的做法)岩睁,而是在第一次需要使用它時才聲明钞脂。 局部變量在聲明時最好就進行初始化,或者聲明后盡快進行初始化捕儒。
4.8.3 數(shù)組
4.8.3.1 數(shù)組初始化:可寫成塊狀結(jié)構(gòu)
數(shù)組初始化可以寫成塊狀結(jié)構(gòu)冰啃,比如,下面的寫法都是OK的:
newint[] {
0, 1, 2, 3
}
newint[] {
0,
1,
2,
3
}
newint[] {
0, 1,
2, 3
}
newint[]{0, 1, 2, 3}
4.8.3.2 非C風格的數(shù)組聲明
中括號是類型的一部分:String[] args
刘莹, 而非 String args[]
阎毅。
4.8.4 switch 語句
術(shù)語說明:switch 塊的大括號內(nèi)是一個或多個語句組。每個語句組包含一個或多個 switch 標簽(case FOO: 或 default:)点弯,后面跟著一條或多條語句扇调。
4.8.4.1 縮進
與其它塊狀結(jié)構(gòu)一致,switch 塊中的內(nèi)容縮進為 2 個空格抢肛。
每個 switch 標簽后新起一行狼钮,再縮進 2 個空格,寫下一條或多條語句捡絮。
4.8.4.2 Fall-through:注釋
在一個 switch 塊內(nèi)熬芜,每個語句組要么通過 break, continue, return
或拋出異常來終止,要么通過一條注釋來說明程序?qū)⒗^續(xù)執(zhí)行到下一個語句組福稳, 任何能表達這個意思的注釋都是 OK 的(典型的是用 // fall through)涎拉。這個特殊的注釋并不需要在最后一個語句組(一般是 default)中出現(xiàn)。示例:
switch (input) {
case1:
case2:
prepareOneOrTwo();
// fall through
case3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}
4.8.4.3 default的情況要寫出來
每個 switch 語句都包含一個 default 語句組的圆,即使它什么代碼也不包含鼓拧。
4.8.5 注解(Annotations)
注解緊跟在文檔塊后面,應(yīng)用于類越妈、方法和構(gòu)造函數(shù)季俩,一個注解獨占一行。這些換行不屬于自動換行(第4.5節(jié)梅掠,自動換行)种玛,因此縮進級別不變。例如:
@Override
@Nullable
public String getNameIfPresent(){ ... }
例外:單個的注解可以和簽名的第一行出現(xiàn)在同一行瓤檐。例如:
@OverridepublicinthashCode(){ ... }
應(yīng)用于字段的注解緊隨文檔塊出現(xiàn),應(yīng)用于字段的多個注解允許與字段出現(xiàn)在同一行娱节。例如:
@Partial@Mock DataLoader loader;
參數(shù)和局部變量注解沒有特定規(guī)則挠蛉。
4.8.6 注釋
4.8.6.1 塊注釋風格
塊注釋與其周圍的代碼在同一縮進級別。它們可以是 /* ... / 風格肄满,也可以是 // ... 風格谴古。對于多行的 / ... */ 注釋质涛,后續(xù)行必須從 * 開始, 并且與前一行的 * 對齊掰担。以下示例注釋都是 OK 的汇陆。
/*
* This is // And so /* Or you can
* okay. // is this. * even do this. */
*/
注釋不要封閉在由星號或其它字符繪制的框架里。
Tip:在寫多行注釋時带饱,如果你希望在必要時能重新?lián)Q行(即注釋像段落風格一樣)毡代,那么使用 /* ... */。
4.8.7 Modifiers
類和成員的 modifiers 如果存在勺疼,則按 Java 語言規(guī)范中推薦的順序出現(xiàn)教寂。
public protected private abstract static final transient volatile synchronized native strictfp
命名約定
5.1 對所有標識符都通用的規(guī)則
標識符只能使用 ASCII 字母和數(shù)字,因此每個有效的標識符名稱都能匹配正則表達式 \w+执庐。
在 Google 其它編程語言風格中使用的特殊前綴或后綴酪耕,如 name\_, mName, s\_name
和 kName
,在 Java 編程風格中都不再使用轨淌。
5.2 標識符類型的規(guī)則
5.2.1 包名
包名全部小寫迂烁,連續(xù)的單詞只是簡單地連接起來,不使用下劃線递鹉。
5.2.2 類名
類名都以 UpperCamelCase
風格編寫盟步。
類名通常是名詞或名詞短語,接口名稱有時可能是形容詞或形容詞短語∈崴洌現(xiàn)在還沒有特定的規(guī)則或行之有效的約定來命名注解類型址芯。
測試類的命名以它要測試的類的名稱開始,以 Test 結(jié)束窜觉。例如谷炸,HashTest或
HashIntegrationTest`。
5.2.3 方法名
方法名都以 lowerCamelCase
風格編寫禀挫。
方法名通常是動詞或動詞短語旬陡。
下劃線可能出現(xiàn)在 JUnit 測試方法名稱中用以分隔名稱的邏輯組件。一個典型的模式是:test<MethodUnderTest>\_<state>
语婴,例如 testPop\_emptyStack
描孟。 并不存在唯一正確的方式來命名測試方法。
5.2.4 常量名
常量名命名模式為 CONSTANT\_CASE
砰左,全部字母大寫匿醒,用下劃線分隔單詞。那缠导,到底什么算是一個常量廉羔?
每個常量都是一個靜態(tài) final
字段,但不是所有靜態(tài) final 字段都是常量僻造。在決定一個字段是否是一個常量時憋他, 考慮它是否真的感覺像是一個常量孩饼。例如,如果任何一個該實例的觀測狀態(tài)是可變的竹挡,則它幾乎肯定不會是一個常量镀娶。 只是永遠不打算改變對象一般是不夠的,它要真的一直不變才能將它示為常量揪罕。
// Constants
staticfinalint NUMBER = 5;
staticfinal ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
staticfinal Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
staticfinal SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }
// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
staticfinal Set<String> mutableCollection = new HashSet<String>();
staticfinal ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
staticfinal Logger logger = Logger.getLogger(MyClass.getName());
staticfinal String[] nonEmptyArray = {"these", "can", "change"};
這些名字通常是名詞或名詞短語梯码。
5.2.5 非常量字段名
非常量字段名以 lowerCamelCase
風格編寫。
這些名字通常是名詞或名詞短語耸序。
5.2.6 參數(shù)名
參數(shù)名以 lowerCamelCase
風格編寫忍些。
參數(shù)應(yīng)該避免用單個字符命名。
5.2.7 局部變量名
局部變量名以 lowerCamelCase
風格編寫坎怪,比起其它類型的名稱罢坝,局部變量名可以有更為寬松的縮寫。
雖然縮寫更寬松搅窿,但還是要避免用單字符進行命名嘁酿,除了臨時變量和循環(huán)變量。
即使局部變量是 final
和不可改變的男应,也不應(yīng)該把它示為常量闹司,自然也不能用常量的規(guī)則去命名它。
5.2.8 類型變量名
類型變量可用以下兩種風格之一進行命名:
- 單個的大寫字母沐飘,后面可以跟一個數(shù)字(如:E, T, X, T2)游桩。
- 以類命名方式(5.2.2節(jié)),后面加個大寫的T(如:RequestT, FooBarT)耐朴。
5.3 駝峰式命名法(CamelCase)
駝峰式命名法分大駝峰式命名法(UpperCamelCase)和小駝峰式命名法(lowerCamelCase)借卧。有時,我們有不只一種合理的方式將一個英語詞組轉(zhuǎn)換成駝峰形式筛峭,如縮略語或不尋常的結(jié)構(gòu)(例如 IPv6 或 iOS)铐刘。Google 指定了以下的轉(zhuǎn)換方案。
名字從散文形式(prose form)開始:
把短語轉(zhuǎn)換為純 ASCII 碼影晓,并且移除任何單引號镰吵。例如:Müller’s algorithm 將變成 Muellers algorithm。
-
把這個結(jié)果切分成單詞挂签,在空格或其它標點符號(通常是連字符)處分割開疤祭。
- 推薦:如果某個單詞已經(jīng)有了常用的駝峰表示形式,按它的組成將它分割開(如AdWords 將分割成 ad words)饵婆。 需要注意的是 iOS 并不是一個真正的駝峰表示形式勺馆,因此該推薦對它并不適用。
-
現(xiàn)在將所有字母都小寫(包括縮寫),然后將單詞的第一個字母大寫:
- 每個單詞的第一個字母都大寫谓传,來得到大駝峰式命名。
- 除了第一個單詞芹关,每個單詞的第一個字母都大寫续挟,來得到小駝峰式命名。
最后將所有的單詞連接起來得到一個標識符侥衬。
示例:
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*
加星號處表示可以诗祸,但不推薦蛾默。
Note:在英語中迂苛,某些帶有連字符的單詞形式不唯一。例如:nonempty 和 non-empty 都是正確的讹蘑,因此方法名 checkNonempty 和 checkNonEmpty 也都是正確的怀樟。
編程實踐
6.1 @Override:能用則用
只要是合法的功偿,就把 @Override
注解給用上。
6.2 捕獲的異常:不能忽視
除了下面的例子往堡,對捕獲的異常不做響應(yīng)是極少正確的械荷。(典型的響應(yīng)方式是打印日志,或者如果它被認為是不可能的虑灰,則把它當作一個 AssertionError
重新拋出吨瞎。)
如果它確實是不需要在 catch
塊中做任何響應(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);
例外:在測試中颤诀,如果一個捕獲的異常被命名為 expected
,則它可以被不加注釋地忽略对湃。下面是一種非常常見的情形崖叫,用以確保所測試的方法會拋出一個期望中的異常, 因此在這里就沒有必要加注釋熟尉。
try {
emptyStack.pop();
fail();
} catch (NoSuchElementException expected) {
}
6.3 靜態(tài)成員:使用類進行調(diào)用
使用類名調(diào)用靜態(tài)的類成員归露,而不是具體某個對象或表達式。
Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad
6.4 Finalizers: 禁用
極少會去重寫 Object.finalize
斤儿。
Tip:不要使用 finalize剧包。如果你非要使用它,請先仔細閱讀和理解 Effective Java 第 7 條款:“Avoid Finalizers”往果,然后不要使用它疆液。
Javadoc
7.1 格式
7.1.1 一般形式
Javadoc 塊的基本格式如下所示:
/**
* Multiple lines of Javadoc text are written here,
* wrapped normally...
*/
publicintmethod(String p1){ ... }
或者是以下單行形式:
/** An especially short bit of Javadoc. */
基本格式總是 OK 的。當整個 Javadoc 塊能容納于一行時(且沒有 Javadoc 標記 @XXX)陕贮,可以使用單行形式堕油。
7.1.2 段落
空行(即,只包含最左側(cè)星號的行)會出現(xiàn)在段落之間和 Javadoc 標記(@XXX)之前(如果有的話)。除了第一個段落掉缺,每個段落第一個單詞前都有標簽 <p>卜录,并且它和第一個單詞間沒有空格。
7.1.3 Javadoc 標記
標準的 Javadoc 標記按以下順序出現(xiàn):@param, @return, @throws, @deprecated, 前面這 4 種標記如果出現(xiàn)眶明,描述都不能為空艰毒。當描述無法在一行中容納,連續(xù)行需要至少再縮進 4 個空格搜囱。
7.2 摘要片段
每個類或成員的 Javadoc 以一個簡短的摘要片段開始丑瞧。這個片段是非常重要的,在某些情況下蜀肘,它是唯一出現(xiàn)的文本绊汹,比如在類和方法索引中。
這只是一個小片段扮宠,可以是一個名詞短語或動詞短語西乖,但不是一個完整的句子。它不會以 A {@code Foo} is a... 或 This method returns... 開頭, 它也不會是一個完整的祈使句涵卵,如 Save the record...浴栽。然而,由于開頭大寫及被加了標點轿偎,它看起來就像是個完整的句子典鸡。
Tip:一個常見的錯誤是把簡單的 Javadoc 寫成 /** @return the customer ID /,這是不正確的坏晦。它應(yīng)該寫成 /* Returns the customer ID. */萝玷。
7.3 哪里需要使用 Javadoc
至少在每個 public 類及它的每個 public
和 protected
成員處使用 Javadoc
,以下是一些例外:
7.3.1 例外:不言自明的方法
對于簡單明顯的方法如 getFoo
昆婿,Javadoc
是可選的(即球碉,是可以不寫的)。這種情況下除了寫 “Returns the foo”仓蛆,確實也沒有什么值得寫了睁冬。
單元測試類中的測試方法可能是不言自明的最常見例子了,我們通晨锤恚可以從這些方法的描述性命名中知道它是干什么的豆拨,因此不需要額外的文檔說明。
Tip:如果有一些相關(guān)信息是需要讀者了解的能庆,那么以上的例外不應(yīng)作為忽視這些信息的理由施禾。例如,對于方法名
getCanonicalName
搁胆, 就不應(yīng)該忽視文檔說明弥搞,因為讀者很可能不知道詞語 canonical name 指的是什么邮绿。
7.3.2 例外:重寫
如果一個方法重寫了超類中的方法,那么 Javadoc 并非必需的攀例。
7.3.3 可選的 Javadoc
對于包外不可見的類和方法船逮,如有需要,也是要使用 Javadoc 的粤铭。如果一個注釋是用來定義一個類傻唾,方法,字段的整體目的或行為承耿, 那么這個注釋應(yīng)該寫成 Javadoc,這樣更統(tǒng)一更友好伪煤。
參考鏈接
- 小土刀 原文
- Google Java Style
- 譯者 @Hawstein