Google Java Style 指南
1 前言
本文檔參考并翻譯自Google Java Style Guide。Google風格官方使用的是2個空格的縮進,國內常用的縮進為4個空格,因此此文檔改為4個空格。同理,自動換行Google是+4個,此處為+8個,switch塊縮進Google是2個,此處為4個。
本文檔作為Java?編程語言中源代碼的Google編碼標準的完整定義。 當且僅當它遵守本文中的規則時,Java源文件才被稱為遵循Google Style。
與其他編程風格指南一樣,所涵蓋的問題不僅包括格式化的審美問題,也包括其他類型的約定或編碼標準。 但是,本文檔主要關注我們普遍遵循的快速規則,并避免提供不可明確強制執行的建議(無論是通過人工還是工具)。
1.1 術語說明
在本文檔中,除非另有說明:
- 術語 class 可表示一個普通類、枚舉類、接口或是注解類型(
@interface
)。 - 術語 member (類的)可表示內部類、變量、方法或是構造函數;即除了初始化代碼塊與注釋以外的類的所有頂級內容。
- 術語 comment 通常用于表示實現的注釋(implementation comments),我們不使用“documentation comments”,而是用“Javadoc”。
其他的“術語說明”則會在后面的文檔偶爾出現。
1.2 指南說明
本文檔中的示例代碼是非規范的。也就是說,雖然示例遵循Google Style,但其并不代表這就是體現代碼優雅的唯一方式。示例中所做的可選格式的選擇不應視為規則強制執行。
2 源文件基礎
2.1 文件名
源文件以其頂級類的類名來命名,大小寫敏感,文件擴展名為.java
。
2.2 文件編碼:UTF-8
源文件編碼格式為UTF-8。
2.3 特殊字符
2.3.1 空白字符
除了行結束符序列,ASCII水平空格字符(0x20,即空格) 是源文件中唯一允許出現的空白字符,這意味著:
- 所有其它字符串中的空白字符都要進行轉義。
- 制表符不用于縮進。
2.3.2 特殊轉義序列
對于具有特殊轉義序列的任何字符(\b
、 \t
、\n
、\f
、\r
、\"
、\'
及\\
),我們使用它的轉義序列,而不是相應的八進制(比如\012
)或Unicode(比如\u000a
)轉義。
2.3.3 非ASCII字符
對于剩余的非ASCII字符,是使用實際的Unicode字符(比如∞
),還是使用等價的Unicode轉義符(比如\u221e
),取決于哪個能讓代碼更易于閱讀和理解。
提示: 在使用Unicode轉義符或是一些實際的Unicode字符時,建議做些注釋給出解釋,這有助于別人閱讀和理解。
例如:
示例 | 結論 |
---|---|
String unitAbbrev = "μs"; |
最佳,即使沒有注釋也非常清晰。 |
String unitAbbrev = "\u03bcs"; // "μs" |
允許,但沒有理由要這樣做。 |
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" |
允許,但這樣做顯得笨拙還容易出錯。 |
String unitAbbrev = "\u03bcs"; |
很糟,讀者根本看不出這是什么。 |
return '\ufeff' + content; // byte order mark |
很好,對于非打印字符,使用轉義,并在必要時寫上注釋。 |
提示: 永遠不要由于害怕某些程序可能無法正確處理非ASCII字符而讓你的代碼可讀性變差。當程序無法正確處理非ASCII字符時,它自然無法正確運行,也就需要修復了。
3 源文件結構
一個源文件按順序包含:
- 許可證或版權信息(如需)
- package語句
- import語句
- 有且僅有一個的頂級類
以上每個部分之間用一個空行隔開。
3.1 許可證或版權信息(如需)
如果一個文件包含許可證或版權信息,那么它應當被放在文件最前面。
3.2 package語句
package語句不換行,列限制(章節4.4)并不適用于package語句。
3.3 import語句
3.3.1 import不要使用通配符
不使用靜態或其他方式的通配符導入。
3.3.2 不要換行
import語句不換行,列限制(章節4.4)并不適用于import語句。
3.3.3 順序和間距
導入順序如下:
- 所有的靜態導入獨立成組。
- 所有的非靜態導入獨立成組。
如果存在靜態和非靜態導入,則單個空白行分隔兩個塊。 import語句之間沒有其他空行。
在每個塊中,導入的名稱以ASCII排序順序顯示。 (注意:這與以ASCII排序順序的import語句不同,因為“.”排在“;”前面。)
3.3.4 沒有靜態導入的類
靜態導入不能用于靜態內部類。它們以普通導入方式導入。
3.4 類聲明
3.4.1 有且僅有一個頂級類
每個頂級類都駐留在自己的源文件中。
3.4.2 類成員順序
類的成員順序對易學性有很大的影響,但這也不存在唯一的通用法則。不同的類對成員的排序可能是不同的。
最重要的一點,每個類應該以某種邏輯去排序它的成員,維護者應該要能解釋這種排序邏輯。比如,新的方法不能總是習慣性地添加到類的結尾,因為這樣就是按時間順序而非某種邏輯來排序的。
3.4.2.1 區塊劃分
當一個類有多個構造函數或者多個同名的方法時,它們順序出現,并且中間沒有其他代碼(包括私有member)。
4 格式化
術語說明:塊狀結構(block-like construct)指的是一個類,方法或構造函數的主體。需要注意的是(章節4.8.3.1),數組初始化中的初始值可被選擇性地視為塊狀結構。
4.1 大括號
4.1.1 使用大括號(即使是可選的)
大括號與if
、else
、for
、do
及while
語句一起使用,即使只有一條語句或是空,也應該把大括號寫上。
4.1.2 非空塊:K & R 風格
對于非空塊和塊狀結構,大括號遵循 Kernighan 和 Ritchie 風格(Egyptian brackets):
- 左大括號前不換行
- 左大括號后換行
- 右大括號前換行
- 右大括號后換行,只有右大括號是一個語句、函數體或類的終止,則右大括號后換行。例如,如果后面跟著
else
或逗號,那么右大括號后面不換行。
示例:
return () -> {
while (condition()) {
method();
}
};
return new MyClass() {
@Override public void method() {
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
} else if (otherCondition()) {
somethingElse();
} else {
lastThing();
}
}
};
章節4.8.1給出了enum類的一些例外。
4.1.3 空塊:可以用簡潔版本
空塊或塊狀構造可以是K&R樣式(如章節4.1.2所述)。 或者,它可以在打開之后立即關閉,在({}
)之間沒有字符或換行符,除非它是多塊語句的一部分(直接包含多個塊:if/else
或try/catch/finally
),即使大括號內沒內容,右大括號也要換行。
示例:
// 這是可以接受的
void doNothing() {}
// 這是同樣可以接受的
void doNothingElse() {
}
// 這是不可接受的: 多塊語句中沒有簡明的空塊
try {
doSomething();
} catch (Exception e) {}
4.2 塊縮進:4個空格
每次打開新的塊或塊狀構造時,縮進增加4個空格。當塊結束時,縮進返回到上一縮進級別??s進級別適用于整個塊中的代碼和注釋。(詳見章節4.1.2中的代碼示例)
4.3 一行一個語句
每個語句后要換行。
4.4 列限制:100
Java代碼的列限制為100個字符。除非如下所述,否則超過此限制的任何行都必須被換行,詳見章節4.5所述。
例外:
- 不可能滿足列限制的行(例如,Javadoc中的一個長URL,或是一個長的JSNI方法參考)。
-
package
和import
語句(見章節3.2和章節3.3)。 - 注釋中那些可能被剪切并粘貼到shell中的命令行。
4.5 自動換行
術語說明: 當合法占用單行的代碼被分為多行時,我們稱之為自動換行(line-wrapping)。
我們并沒有全面,確定性的準則來決定在每一種情況下如何自動換行。很多時候,對于同一段代碼會有好幾種有效的自動換行方式。
說明: 雖然自動換行的典型原因是為了避免溢出列限制,但事實上符合列限制的代碼也可以自動換行,這由代碼作者自行決定。
提示: 通過提取方法或局部變量可以解決不得不自動換行的問題。
4.5.1 從哪里斷開
自動換行的基本準則是:更傾向于在更高的語法級別處斷開。如:
- 如果在非賦值運算符處斷開,那么在該符號前斷開。(注意:這一點與 Google 其它語言的編程風格不同,如 C++ 和 JavaScript。)這條規則也適用于以下"類運算符"符號:
- 點分隔符(
.
) - 一個方法引用的兩個冒號(
::
) - 類型界限中的 &(
<T extends Foo & Bar>
) - 捕獲塊中的管道符號(
catch (FooException | BarException e)
)。
- 如果在賦值運算符處斷開,通常在該符號后斷開,但是在符號之前也是可以接受的。
- 這條規則也適用于foreach語句中的冒號。
- 方法名或構造函數名與左括號(
(
)留在同一行。 - 逗號(
,
)與其前面的內容留在同一行。 - 在Lambda表達式中,一行從不會被斷開,除了如果Lambda表達式的主體由單個非支持表達式組成,則可能會在箭頭之后立即出現斷開。示例:
MyLambda<String, Long, Object> lambda =
(String label, Long value, Object obj) -> {
...
};
Predicate<String> predicate = str ->
longExpressionInvolving(str);
說明: 自動換行的主要目的是為了使代碼更為清晰,但對代碼要求行數越少越好,則自動換行就沒有必要了。
4.5.2自動換行時縮進至少+8個空格
自動換行時,第一行后面的每一行(每個連續行)從原始行縮進至少增加8個空格。
當存在連續自動換行時,縮進可能會多縮進不只8個空格(語法元素存在多級時)。一般而言,兩個連續行使用相同的縮進當且僅當它們開始于同級語法元素。
章節4.6.3水平對齊一節中指出,不鼓勵使用可變數目的空格來對齊前面行的符號。
4.6 空白
4.6.1 垂直空白
以下情況需要使用一個空行:
- 類內連續的成員之間:字段,構造函數,方法,嵌套類,靜態初始化塊,實例初始化塊。
- 例外: 兩個連續字段之間的空行(在它們之間沒有其他代碼)是可選的。這樣的空白行根據需要用于創建字段的邏輯分組。
- 例外: 枚舉常量之間的空行,章節4.8.1將介紹。
- 在函數體內,語句的邏輯分組間使用空行。
- 類內的第一個成員前或最后一個成員后的空行是可選的。(既不鼓勵也不反對這樣做,視個人喜好而定。)
- 要滿足本文檔中其他節的空行要求。(比如章節3:源文件結構及章節3.3:import語句)
多個連續的空行是允許的,但沒有必要這樣做(也不鼓勵這樣做)。
4.6.2 水平空白
除了語言需求和其它規則,并且除了文字,注釋和Javadoc用到單個空格,單個ASCII空格僅出現在以下幾個地方:
- 分隔任何保留字(如:
if
、for
及catch
)與緊隨其后的左括號((
)。 - 分隔任何保留字(如:
else
或catch
)與其前面的右大括號(}
)。 - 在任何左大括號前(
{
),兩個例外:
-
@SomeAnnotation({a, b})
(不使用空格) -
String[][] x = {{"foo"}};
(兩個大括號之間無空格)
- 在任何二元或三元運算符的兩側。這也適用于以下"類運算符"符號:
- 類型界限中的&符:
<T extends Foo & Bar>
- catch塊中的管道符號:
catch (FooException | BarException e)
- foreach語句中的冒號(
:
)。
- 在
, : ;
及右括號()
)后 - 如果在一條語句后做注釋,則雙斜杠(
//
)兩邊都要空格。這里可以允許多個空格,但沒有必要。 - 類型和變量之間:
List<String> list
- 在數組初始值設定符的兩個大括號內可選
-
new int[] {5, 6}
與new int[] { 5, 6 }
都可行
此規則不應理解為在行的開始或結束處要求或禁止額外的空格; 它只涉及行的內部空格。
4.6.3 水平對齊:不做要求
術語說明: 水平對齊指的是通過增加可變數量的空格來使某一行的字符與上一行的相應字符對齊。
這是允許的,但Google編程風格對此不做要求。即使對于已經使用水平對齊的代碼,我們也不需要去保持這種風格。
以下示例先展示未對齊的代碼,然后是對齊的代碼:
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
說明: 對齊可增加代碼可讀性,但它為日后的維護帶來問題。考慮未來某個時候,我們需要修改一堆對齊的代碼中的一行。
這可能導致原本很漂亮的對齊代碼變得錯位。很可能它會提示你調整周圍代碼的空白來使這一堆代碼重新水平對齊(比如程序員想保持這種水平對齊的風格)。這就會讓你做許多的無用功,增加了reviewer的工作并且可能導致更多的合并沖突。
4.7 用小括號來限定組:推薦
除非作者和reviewer都認為去掉小括號也不會使代碼被誤解,或是去掉小括號能讓代碼更易于閱讀,否則我們不應該去掉小括號。我們沒有理由假設讀者能記住整個Java運算符優先級表。
4.8 具體結構
4.8.1 枚舉類
枚舉常量間用逗號隔開,換行可選。 還允許附加空行(通常只有一個)。 這是一個樣例:
private enum Answer {
YES {
@Override public String toString() {
return "yes";
}
},
NO,
MAYBE
}
沒有方法和文檔的枚舉類可寫成數組初始化的格式(詳見章節4.8.3.1)。
private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }
由于枚舉類也是一個類,因此所有適用于其它類的格式規則也適用于枚舉類。
4.8.2 變量聲明
4.8.2.1 每次只聲明一個變量
不要使用組合聲明,如int a, b;
。
4.8.2.2 需要時才聲明,并盡快進行初始化
不要在一個代碼塊的開頭把局部變量一次性都聲明了,而是在第一次需要使用它時才聲明。局部變量在聲明時最好就進行初始化,或者聲明后盡快進行初始化。
4.8.3 數組
4.8.3.1 數組初始化:可寫成塊狀結構
數組初始化可以寫成塊狀結構,比如,下面的寫法都是可行的:
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風格的數組聲明
中括號是類型的一部分:String[] args
, 而非 String args[]
。
4.8.4 switch語句
術語說明: switch塊的大括號內是一個或多個語句組。每個語句組包含一個或多個switch標簽(case FOO:
或default:
),后面跟著一條或多條語句(最后一個語句組后面沒有語句或者跟著多條語句)。
4.8.4.1 縮進
與其它塊狀結構一致,switch塊中的內容縮進為4個空格。每個switch標簽后新起一行,再縮進4個空格,寫下一條或多條語句。
4.8.4.2 Fall-through:注釋
在一個switch塊內,每個語句組要么通過break
、continue
、return
或拋出異常來終止,要么通過一條注釋來說明程序將繼續執行到下一個語句組, 任何能表達這個意思的注釋都是可行的(典型的是用// fall through
)。這個特殊的注釋并不需要在最后一個語句組中出現。示例:
switch (input) {
case 1:
case 2:
prepareOneOrTwo();
// fall through
case 3:
handleOneTwoOrThree();
break;
default:
handleLargeNumber(input);
}
注意,在case 1
后面不需要注釋,只有在語句組的末尾需要。
4.8.4.3 default
的情況要寫出來
每個switch語句包括一個default
語句組,即使它不包含代碼。
例外:enum
類型的switch語句可以省略default
語句組,如果它包括覆蓋該類型的所有可能值的顯式情況。這使IDE或其他靜態分析工具能夠在錯過任何情況時發出警告。
4.8.5 注解(Annotations)
注解緊跟在文檔塊后面,應用于類、方法和構造函數,一個注解獨占一行。這些換行不屬于自動換行(章節4.5,自動換行),因此縮進級別不變。示例:
@Override
@Nullable
public String getNameIfPresent() { ... }
例外: 單個的注解可以和簽名的第一行出現在同一行。如:
@Override public int hashCode() { ... }
應用于字段的注解緊隨文檔塊出現,應用于字段的多個注解允許與字段出現在同一行。如:
@Partial @Mock DataLoader loader;
參數和局部變量注解沒有特定規則。
4.8.6 注釋
本節討論實現注釋。 Javadoc在章節7 Javadoc中單獨講解。
任何換行符之前可以有任意空格,然后是實現注釋。這樣的注釋使該行非空白。
4.8.6.1 塊注釋風格
塊注釋與其周圍的代碼在同一縮進級別。它們可以是/* ... */
風格,也可以是// ...
風格。對于多行的/* ... */
注釋,后續行必須以*
開始, 并且與前一行的*
對齊。
/*
* This is
* okay.
*/
// And so
// is this.
/* Or you can
* even do this. */
注釋不要封閉在由星號或其它字符繪制的框架里。
提示: 當編寫多行注釋時,如果您希望自動代碼格式化程序在必要時重新換行(段落樣式),請使用
/* ... */
樣式。大多數格式化程序不會在// ...
樣式注釋塊中重新換行。
4.8.7 修飾符
類和成員的修飾符如果存在,則按Java語言規范中推薦的順序出現。
public protected private abstract default static final transient volatile synchronized native strictfp
4.8.8 數字字面量
long
數值使用大寫L
后綴,而非小寫(以避免與數字1
混淆)。例如,3000000000L
而不是3000000000l
。
5 命名約定
5.1 對所有標識符都通用的規則
標識符只能使用ASCII字母和數字,因此每個有效的標識符名稱都能匹配正則表達式\w+
。
在Google Style中,特殊的前綴或后綴不使用在示例中看到的如name_
、mName
、s_name
和kName
。
5.2 標識符類型的規則
5.2.1 包名
包名稱都是小寫,連續的單詞連接在一起(無下劃線)。如com.example.deepspace
而非com.example.deepSpace
或com.example.deep_space
。
5.2.2 類名
類名都以UpperCamelCase風格編寫。
類名通常是名詞或名詞短語(如:Character
或ImmutableList
),接口名稱通常也是名詞或名詞短語(如List
),但有時可能是形容詞或形容詞短語(如Readable
)。
現在還沒有特定的規則或行之有效的約定來命名注解類型。
測試類從它們正在測試的類的名稱開始命名,并以Test
結束。例如,HashTest
或HashIntegrationTest
。
5.2.3 方法名
方法名都以lowerCamelCase風格編寫。
方法名稱通常是動詞或動詞短語。 例如,sendMessage
或stop
。
下劃線可能出現在JUnit測試方法名稱中,用以分隔名稱的邏輯。一個典型的模式是test<MethodUnderTest>_<state>
,例如testPop_emptyStack
。尚未出現給測試方法命名的標準命名準則。
5.2.4 常量名
常量名命名模式為CONSTANT_CASE
,全部字母大寫,用下劃線分隔單詞。那,到底什么算是一個常量?
常數是靜態final字段,其內容是不可變的,并且其方法沒有可檢測的函數副作用。這包括基元,字符串,不可變類型和不可變類型的不可變集合。如果任何實例的觀測狀態可以改變,它就不是一個常量。靜態final字段不一定都是常量。例如:
// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final ImmutableMap<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
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 ImmutableMap<String, SomeMutableType> mutableValues =
ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};
這些名字通常是名詞或名詞短語。
5.2.5 非常量字段名
非常量字段名(靜態或其他)以lowerCamelCase風格編寫。
這些名稱通常是名詞或名詞短語。 例如,computedValues
或index
。
5.2.6 參數名
參數名以lowerCamelCase風格編寫。
應該避免公共方法中的單字符參數名稱。
5.2.7 局部變量名
局部變量名以lowerCamelCase風格編寫。
即使局部變量是final和不可改變的,也不應該把它示為常量,自然也不能用常量的規則去命名它。
5.2.8 類型變量名
類型變量可用以下兩種風格之一進行命名:
- 單個的大寫字母,后面可以跟一個數字(如:
E
、T
、X
、T2
)。 - 以類命名方式(章節5.2.2),后面加個大寫的
T
(如:RequestT
、FooBarT
)。
5.3 CamelCase:定義
有時不止一種合理的方式可以將短語轉換為CamelCase模式,例如首字母縮略詞或不尋常的結構,如“IPv6”或“iOS”。為了提高可預測性,Google Style指定(盡量)使用以下確定性方案。
從名稱的文本形式開始:
- 將短語轉換為純ASCII并刪除任何省略號。例如:“Müller's algorithm”可改為“Muellers algorithm”。
- 以空格和任何剩余的標點符號(通常為連字符)將結果劃分為單詞。
- 推薦: 如果有任何詞在常用的情況下已經具有常規的CamelCase外觀,將其拆分為其組成部分(例如,“AdWords”成為“ad words”)。 注意,諸如“iOS”這樣的詞本身不是真正的駱駝情況;它違反任何慣例,因此本建議不適用。
- 將單詞(包括首字母縮略詞)第一個字符大寫其他字符全小寫:
- ...將所有字符全大寫
- ...除第一個字符外,將所有字符全小寫
- 最后,將所有單詞連接成一個詞。
注意,原始單詞樣式幾乎完全被忽略。示例:
文本形式 | 正確 | 錯誤 |
---|---|---|
"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 編程實踐
6.1 @Override
:能用則用
只要是合法的,就把@Override
注解給用上。這包括重寫超類方法的類方法,實現接口方法的類方法,以及重定義超接口方法的接口方法。
例外: 當父方法為@Deprecated
時,可以省略@Override
。
6.2 捕獲的異常:不能忽視
除下面的例子,對捕獲的異常不做響應極少是正確的。(典型的響應方式是打印日志,如果不行,則把它當作一個AssertionError
重新拋出。)
如果它確實是不需要在catch塊中做任何響應,需要做注釋加以說明(如下面的例子)。
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 靜態成員:使用類進行調用
使用類名調用靜態的類成員,而不是具體某個對象或表達式。
Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad
6.4 Finalizers: 禁用
極少會去重載Object.finalize
。
提示: 不要這么做,不得已非要這么做的話,請先仔細閱讀并理解Effective Java Item 7: "Avoid Finalizers",非常小心,最后還是不要這么做。
7 Javadoc
7.1 格式
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. */
基本形式總是可以接受的。當整個Javadoc塊(包括注釋標記)可以放在單個行上時,可以將其替換為單行形式。注意,這只適用于沒有塊標簽的情形,如@return
。
7.1.2 段落
空行(即僅包含對齊的前導星號(*
)的行)出現在段落之間,并在Javadoc標記(如果存在)之前。除了第一個段落,每個段落第一個單詞前都有標簽<p>
,并且它和第一個單詞間沒有空格。
7.1.3 Javadoc標記
標準的Javadoc標記按以下順序出現:@param
、@return
、 @throws
、@deprecated
,且這四種類型不能出項空描述。當描述無法在一行中容納時,連續行需要至少在@
縮進的基礎上再縮進至少4個空格。
7.2 摘要片段
每個類或成員的Javadoc以一個簡短的摘要片段開始。這個片段是非常重要的,在某些情況下,它是唯一出現的文本,比如在類和方法索引中。
這只是一個小片段,可以是一個名詞短語或動詞短語,但不是一個完整的句子。它不會以A {@code Foo} is a...
或This method returns...
開頭,它也不會是一個完整的祈使句,如Save the record.
。然而,由于開頭大寫及被加了標點,它看起來就像是個完整的句子。
提示: 一個常見的錯誤是把簡單的Javadoc寫成
/** @return the customer ID */
,這是不正確的。它應該寫成/** Returns the customer ID. */
。
7.3 何處需要使用Javadoc
至少在每個public類及它的每個public和protected成員處使用Javadoc,以下是一些例外。
也可能存在其他Javadoc內容,如章節7.3.3所述。
7.3.1 例外:不言自明的方法
對于簡單明顯的方法如getFoo
,Javadoc是可選的。這種情況下除了寫"Returns the foo",確實也沒有什么值得寫了。
提示: 如果有一些相關信息是需要讀者了解的,那么以上的示例不應作為忽視這些信息的理由。例如,對于名為
getCanonicalName
的方法,不要省略其文檔(文檔可以僅僅是/** Returns the canonical name. */
),可能讀者并不明白“canonical name”具體指什么
7.3.2 例外:重載
如果一個方法重載了超類中的方法,那么Javadoc并非必需的。
7.3.3 非必需Javadoc
對于包外不可見的類和方法,如有需要,也是要使用Javadoc的。
如果一個注釋是用來定義一個類,方法,字段的整體目的或行為,那么這個注釋應該寫成Javadoc(使用/**
)。
不一定要求非必需的Javadoc遵循章節7.1.2、章節7.1.3和章節7.2的格式化規則,當然也是建議遵循的。