Google Java Style (非公式和訳)


この文書について

本文書はGoogleのJavaコーディング規約: Google Java Style の非公式和訳である。 原文の 2014/03/21 Revision: r130 版に対応する。
技術的に正確であろうとはしているが、訳者は訳の正確性および、原文の更新に追従することについて保証はしない。
もともとは 福原和朗 氏が訳して githubにて公開しているもの を、奥田が一部改訳したものである。よって、福原氏の訳に起因する問題も含めて誤訳などの指摘は歓迎するが、奥田が改訳した箇所の誤りについて、福原氏の手を煩わせることが無いよう注意されたい。


1 導入

2 ソースファイルの基本事項

3 ソースファイル構造

4 フォーマット

5 命名

6 プログラミングの実践

7 Javadoc

1 導入

この文書はJava™プログラミング言語のソースコードのGoogleのコーディング標準の 完全 な定義を提供する。下記のルールに従うJavaソースファイルのみが、Googleスタイルであるとみなされる。

他のプログラミングスタイルガイドのように、問題の対象範囲は審美的なフォーマットの問題だけでなく他の種類の規約やコーディング標準も含まれる。しかしながらこの文書は私達が全世界的に従う 当然の規則 に優先的に注力しており、(人力か機械処理のいずれによっても)実施可能かどうかが不明確な お節介 は除いている。

1.1 用語についての注記

本文書において、特別に断りのない限り、

  1. クラスという用語は、「通常の」クラス、列挙型 、インターフェース、アノテーション型(@interface)を包括的に意味する。
  2. コメントという用語は、常にインプリメンテーションコメントを意味する。「ドキュメンテーションコメント」という言い方は使わない。代わりに「Javadoc」という一般的な用語を使う。

本文書では他の用語についての注記は文書中にて適宜行う。

1.2 ガイドについての注記

この文書内のサンプルコードは 規定の一部ではない (non-normative)。 つまり、サンプルコードはGoogleスタイル文書に書かれているが、これが 唯一 のスタイルに従ったコーディングの例だというわけではない。例に出される補足的なフォーマットの仕方はルールとして強制すべきではない。

2 ソースファイルの基本事項

2.1 ファイル名

ソースファイル名はそれが入っているトップレベルクラスの大文字小文字を区別した名前と加えて .java という拡張子が付いていること。

2.2 ファイルエンコーディング:UTF-8

ソースファイルは UTF-8 でエンコードされていること。

2.3 特殊文字

2.3.1 空白

改行を除いては、 ASCII 水平スペース文字 (0×20) はソース内でどこに現れても良い唯一の空白文字である。すなわち、

  1. Stringと文字リテラルでのこれ以外の空白文字はエスケープすること。
  2. タブ文字をインデントの目的で 使ってはいけない。

2.3.2 特別なエスケープシーケンス

特別なエスケープシーケンスを持つ全ての文字(\b, \t, \n, \f, \r, \", \' と \\)については8進数表記(\012)やUnicodeエスケープ(\u000a)でなく、通常のエスケープシーケンスで表記する。

2.3.3 非ASCII文字

残りの非ASCII文字については ソースコードを読むことや理解することが簡単になる かどうかのみを基準にして実際のUnicode文字(例:∞)あるいは同等のUnicodeエスケープ(例: \u221e)を使うかの判断を行う。

TIP: Unicodeエスケープの場合時たま実際にUnicode文字が使われている時でも、説明のコメントがあるとわかりやすい。

説明
String unitAbbrev = "μs"; 最良。コメントなしでも完全で明確
String unitAbbrev = "\u03bcs"; // "μs" 許容される。しかしこう書く理由はない
String unitAbbrev = "\u03bcs"; // ギリシャ文字ミューと "s" 許容される。しかし奇妙で間違えやすい
String unitAbbrev = "\u03bcs"; だめ。読者やこれが何なのか分からない
return '\ufeff' + content; // バイトオーダーマーク 良い。表示されない文字にはエスケープを使い必要ならコメントする

TIP: 何かのプログラムが非ASCII文字を正しく処理しないからというだけの理由でコードを読みにくくしてはならない。もしそのような事が起こる場合はそのプログラムが 壊れている のであって、そちらが 修正される べきである。

3 ソースファイル構造

ソースファイルの内容は 以下の順序 であること。

1. ライセンスあるいはコピーライトの情報(もしあるならば)
2. package文
3. import文
4. ただ1個のトップレベルクラス。

それぞれの分離には ただ1行の空行 を使うこと。

もしファイルにライセンスあるいはコピーライトの情報があるならばここに入る。

3.2 パッケージ文

パッケージ文は 改行してはならない。 文字数制限(4.4節文字数制限は80あるいは100文字)はパッケージ文には適用されない。

3.3 インポート文

3.3.1 ワイルドカードインポートは禁止

ワイルドカードインポート はstaticであってもなくても 使ってはならない。

3.3.2 改行禁止

import文は 改行してはならない。 文字数制限(4.4節文字数制限は80あるいは100文字)はimport文には適用されない。

3.3.3 順序と空白

インポート文は以下のグループに以下の順序で分けられる。グループは1行の空白で分離される。

  1. すべてのstatic importを単一のグループにまとめる。
  2. com.google のインポート。(ソースファイルが com.google パッケージに属する場合のみ)
  3. サードパーティのインポート。トップレベルパッケージ毎に1個のグループとしASCII文字の順序で
  4. java パッケージのインポート
  5. javax パッケージのインポート

空行が入らないグループ毎にインポートした名前はASCII順に並べなければならない。( 注釈: これはインポート文全体がASCII順になっていることとは異なる。行末のセミコロンを含めての並び替えの結果は、期待通りのものではない。)

3.4 クラス宣言

3.4.1 1個だけのトップレベルクラスの宣言

各トップレベルクラスは1個のファイルに保存される。

3.4.2 クラスメンバーの順序

クラスメンバーの順序はわかりやすさに多大な影響を与えるが唯一の解法は無い。異なるクラスには異なるメンバーの並べ方があってよい。

いずれのクラスのメンバー順も、誰かに訊かれた時に答えられるような 何らかの論理的な順序 であることが重要である。例えば新しいメソッドはクラスの最後に惰性で追加してはならない。それは「追加された日の順」になっているだけであって、論理的な順序ではない。

3.4.2.1 オーバーロードしているメソッド群を分離してはならない

クラスに複数のコンストラクタや同じ名前を持つメソッドがある場合は連続して並べる。間に別のメンバーを入れてはならない。

4 フォーマット

用語についての注釈: 「ブロック様の構造物(block-like construct)」とは、クラス、メソッド、コンストラクタの本体を指す。配列初期化子は場合により「ブロック様の構造物」とみなしてもよい。4.8.3.1節 配列初期化子を参照。

4.1 中括弧

4.1.1 使えるところでは中括弧は使う

if else for do while 文において、中身が空文でも1文のみでも、中括弧で囲うこと。

4.1.2 空でないブロックではK&Rスタイルに従う

中括弧は空でないブロックや、ブロック様の構造物ではカーニハン・リッチースタイル(Egyptian Brackets )に従う。

例:

return new MyClass() {
  @Override public void method() {
    if (condition()) {
      try {
        something();
      } catch (ProblemException e) {
        recover();
      }
    }
  }
};

列挙型でのいくつかの例外はセクション4.8.1 列挙型にて示される。

4.1.3 空ブロックは簡潔に

空ブロックや空のブロックのような構造物は開始括弧直後に文字や改行無しで閉じてよい。( {}但し、 if/else-if/else あるいは try/catch/finally のような複数ブロックの文の場合を除く。

例:

void doNothing() {}

4.2 ブロックのインデントは空白2個である

新しいブロックあるいはブロック様の構造物が開始した時インデントは空白2個づつ増える。ブロックが終了したら、インデントは1個まえのレベルに戻る。インデントレベルはブロックを通じてコードとコメントに適用される。4.1.2節の例を参照のこと。( 4.1.2 空でないブロックではK&Rスタイルに従う。)

4.3 1行毎に1個の文

各文は、末尾に改行が来なくてはならない。

4.4 1行の文字数制限 80文字か100文字

プロジェクトごとに1行の文字数制限を80文字か100文字いずれかで自由に決定して良い。以下の例外を除き、この制限を超えた行は4.5節 行の折り返しで述べるように改行されなくてはならない。

例外:

1. 文字数制限に従うのが不可能の場合。(例えば、Javadoc内の長いURL、長いJSNIメソッド参照)
2. パッケージ文とインポート文 (3.2 パッケージ文 と3.3 インポート文を参照のこと)
3. コメント内の、コンソールにコピー&ペーストされるようなコマンド。

4.5 行の折り返し

用語の注記: 正当だが単一行が長いコードを複数行に分けるとき(典型的には一行あたりの文字数制限の回避)、この活動を行の折り返しと呼ぶ。

どんな状況にも合う改行方法を正確に示すような統一的で決定的なやり方はない。同じコード片を改行する正しい方法は、しばしば複数あるものだ。

TIP: メソッドやローカル変数の抽出を行えば、改行をせずに問題が片付くことがある。

4.5.1 どこで改行するか

改行の第一原則は、 高い文法のレベル で改行することである。つまり、

  1. 代入でない演算子で改行するときは、シンボルの前で改行する。(注:これはJavaScriptやC++のような他の言語でのGoogleスタイルでの慣習とは異なる。)
  2. 行が代入演算子で改行されるときは、通常は代入演算子の後ろに改行を入れる。しかし、代入演算子の前に改行を入れることも許容される。
  3. メソッドやコンストラクタ名と、それに続く開始括弧(()の間には改行を入れないこと。
  4. カンマ( , )とその前のトークンの間には改行を入れないこと。

4.5.2 連続する行は少なくとも4文字インデントする

改行の際、連続する先頭行のに続く各行は少なくとも空白4個分元からインデントする。

複数の連続した行がある場合、インデントは4以上ならいくつでも良い。一般的に、2個の連続した行がもし文法的に並行した要素で始まるならばそのときのみ同じインデントレベルであるべきだ。

“4.6.3節の水平位置揃えは全く不要”は、あるトークンを前の行に揃えるため必要な分の空白を入れるというまずいやり方を避けるものである。

4.6 空白

4.6.1 垂直の空白

以下の場合において、単一の空行を入れる。

  1. クラスの連続するメンバ(あるいは初期化子)の間。フィールド、コンストラクタ、メソッド、ネストしたクラス、static初期化子、インスタンス初期化子。
  2. メソッド本体内で、文を論理的にグループ分けしたい場合。
  3. 必要な場合、クラスの最初のメンバーの前と最終メンバーの後。(推奨も拒否もしない)
  4. 本文書の別の節で入れるよう求められた場所(3.3節のインポート文など)

複数の連続した空行を入れて良いが、必須でも推奨でもない。

4.6.2 水平の空白

言語かあるいは他のスタイルルールの要求事項を除いては、リテラル、コメント、Javadoc以外で単一のASCII空白は以下の場所 のみ において使って良い。

  1. 予約語( if, for , catch )とその行での開始小括弧 ( ( )の間。
  2. 予約語( else, catch )とその行での前に来る終了中括弧( } )との間。
  3. 開始中括弧( { )の前すべて。ただし以下の2個の例外を除く
  4. すべての二項ないし三項演算子の両側。また、以下の様な演算子ライクな記号にも適用する。
  5. , : ; あるいはキャストの閉じ括弧 ( ) ) の後ろ。
  6. 行末コメントを開始するスラッシュ2個( // )の両側。ここでは複数の空白が許されるが必須ではない。
  7. 型と変数の宣言の間。 List<String> list
  8. 任意で、配列初期化子の両括弧の中。

注意:このルールは行頭行末の空白について要求も禁止もしない。内側の空白のみについて当てはまる。

4.6.3 水平位置揃えは全く不要

用語の注釈: 水平位置揃えとは、前行のトークン(変数名、型名)の真下に次行のトークンが来るように入れるスペース数を調整することである。

行ってもよいが、がGoogleスタイルでは 決して要求されない。 すでにこうなっている箇所をそのまま 維持 する必要もない。

これは水平位置揃えを行っている例と行っていない例だ。

private int x; // これは良い
private Color color; // これも良い

private int   x;      // 許容される。しかし今後の編集で
private Color color;  // 揃えられなくなるかもしれない。

Tip: カラムの調整は可読性を上げるが将来の変更で問題になる。一行だけ直したいときを考えてほしい。この変更は以前のきれいな並びをおかしくするだろう。このようなことが 発生しうる。 このことは開発者(多分君)に近くの行を同様になおせと求める。そして修正範囲の拡大を引き起こす。一行の変更が長大な変更となる。最悪意味のない作業になる。良くても変更履歴を汚くする。レビューが遅くなり、マージの衝突がおこるようになる。。

4.7 グループ化の括弧 推奨

追加のグループ化の括弧は作者とレビュアーが括弧なしでもコードは誤解される余地がないと認めるか、括弧を無くすことでコードが読みやすくなる場合のみ許される。すべての読者がJava演算子の優先度表を記憶していると仮定するのは合理的ではない。

4.8 各構造物

4.8.1 列挙型

列挙定数値後の各カンマの後ろの改行は任意である。

定数値にメソッドもドキュメンテーションもない列挙型は必要に応じて任意に配列初期化子と同様に整形してよい。(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[] {           new int[] {
  0, 1, 2, 3            0,
}                       1,
                        2,
new int[] {             3,
  0, 1,               }
  2, 3
}                     new int[]
                          {0, 1, 2, 3}
4.8.3.2 Cのような配列宣言は禁止

角括弧囲みは型の一部であって、変数の一部ではない(訳注:…のだから、変数名の後ろに[]を置くことで配列の宣言をするC言語風表記は使うべきではない)。 String[] args は良い。 String args[] はダメ。

4.8.4 スイッチ文

用語についての注釈 スイッチブロックの括弧の内側は一個以上の文グループである。それぞれの文グループは一個以上のスイッチラベル( case FOO: でも default: であっても)とそれに続く続く一個以上の文である。
4.8.4.1 インデンテーション

他のブロック同様、スイッチブロックを2つの空白でインデントすること。

スイッチラベルの後に改行を入れ、あたかもブロックが開始したかのようにインデントレベルを2上げること。次のスイッチラベルはあたかもブロックの終わったように前のインデンテーションレベルに戻すこと。

4.8.4.2 フォールスルー コメントを入れる

スイッチブロック内では、各文グループで処理を終わらせる( breakcontinuereturn か例外スローか)のでなければ、実行が次の文グループに進む旨のコメントを必ず付けよ。フォールスルーということを示すコメントも効果的である (典型的には // fall through )。この特別なコメントは、最後の文グループには必要ない。

例えば:

switch (input) {
 case 1:
 case 2:
   prepareOneOrTwo();
   // fall through
 case 3:
   handleOneTwoOrThree();
   break;
 default:
   handleLargeNumber(input);
}
4.8.4.3 default 節は必要

各スイッチ文は、たとえコードを含まないとしても、 default 文グループを含めること。

4.8.5 アノテーション

クラス、メソッド、コンストラクタに付けられるアノテーションは、ドキュメンテーションブロックの直後に置くこと。アノテーションは1行に1個とすること。これらの改行は行折り返し(4.5 節 行折り返し) に従わない。それ故、インデンテーションレベルも上げない。例えば:

@Override
@Nullable
public String getNameIfPresent() { ... }
例外: パラメータ無しのアノテーションが1個だけの場合はシグネチャー行の先頭に置いてもよい。例えば:
@Override public int hashCode() { ... }

フィールドへのアノテーションもドキュメンテーションブロックの直後に置くが、複数のアノテーション(パラメタ化されているものも含む)が同じ行に現れても良い。例えば:

@Partial @Mock DataLoader loader;

パラメータや、ローカル変数へのアノテーションについては特にルールはありません。

4.8.6 コメント

4.8.6.1 ブロックコメントスタイル

ブロックコメントは周りのコードと同じレベルにインデントされる。 /* ... */ でも //... でも同じである。複数行 /* ... */ コメントについては * の位置を前の行の * と同じに揃えなくてはならない。

/*
 * これは         // これも           /* こんなかたち
 * 良い           // 良い              * であっても良い。 */
 */

コメントはアスタリスクや他の文字で描かれた箱で囲わない。

Tip: 複数行コメントを書く際必要に応じ自動フォーマット機能で行折り返ししたい場合は /* ... */ スタイルを使うと良い。多くのフォーマッタは // ... スタイルのコメントの改行を直さない。

4.8.7 修飾子

クラスやメンバの修飾子はJava言語仕様が推奨する順序で出現しなくてはならない。

public protected private abstract static final transient volatile synchronized native strictfp

4.8.8 数値リテラル

long型の数値リテラルは大文字の L を末尾に使う。小文字のlは使わない(数値 1 との混乱を避けるため)。例えば 3000000l ではなく 300000L を使う。

5 命名

5.1 すべての識別子への共通ルール

識別子はASCIIコード内の文字、数字、および後述のうち2ケース(訳注:5.2.4の定数名と、5.2.3のメソッド名のうちJUnitのテストメソッド名の場合)に限ってアンダースコアを使う。それゆえ、有効な識別子名は正規表現 \w+ にマッチする。

Googleスタイルでは、 name_mNames_namekName といったような特別な接尾辞・接頭辞は使わない。

5.2 識別子の種類ごとのルール

5.2.1 パッケージ名

パッケージ名はすべて小文字で連続する単語をそのまま繋げる。アンダースコアは使わない。例えば、 com.example.deepspace であって、 com.example.deepSpacecom.example.deep_space は使わない。

5.2.2 クラス名

クラス名は大文字キャメルケース(UpperCamelCase)で命名する。

クラス名は大抵名詞か名詞句である。例えば、 Character や、 ImmutableList である。インターフェース名も名詞か名詞句である。例えば List である。しかし、場合によっては形容詞や形容詞句になる。例えば、 Readable である。

アノテーション型に対する特定のルールや確立した規約はない。

テストクラスはテスト対象クラス名で始まり、 Test で終わるよう命名する。例えば HashTest や、 HashIntegrationTest である。

5.2.3 メソッド名

メソッド名は、小文字キャメルケース(lowerCamelCase)で命名する。

メソッド名は大抵動詞か動詞句である。例えば、 sendMessagestop である。

アンダースコアはJUnitのメソッド名で、論理的コンポーネント名を分離する場合に使ってよい。典型的なパターンは test<テスト対象メソッド名>_<状態> で、例えば testPop_emptyStack のような場合である。テストメソッドを命名する正しい唯一の方法はない。

5.2.4 定数名

定数は コンスタントケース(CONSTANT_CASE)で命名する。すべて大文字で、各単語をアンダースコアで区切る。しかし定数とはそもそも何であろうか?

すべての定数は static final なフィールドである。しかし、すべての static final なフィールドが定数であるとは限らない。
コンスタントケースを選ぶ前に、そのフィールドが定数と 感じられるか を一考すべきだ。例えば、そのインスタンスの可視な状態が変更できるならば、殆どの場合定数ではない。決して変更されないオブジェクトの振りをするだけでは大抵不十分である。例えば、

// 定数である
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Joiner COMMA_JOINER = Joiner.on(',');  // Joiner は不変であるので。
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }

// 定数でない
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 定数でないフィールド名

定数でないフィールド名(staticであってもなくても)は小文字キャメルケース(lowerCamelCase)で命名する。

これらの名前は大抵名詞か名詞句である。例えば computedValuesindex である。

5.2.6 パラメータ名

パラメータ名は小文字のキャメルケース(lowerCamelCase)で命名する。

一文字のパラメータ名は避けるべきである。

5.2.7 ローカル変数名

ローカル変数名は小文字キャメルケース(lowerCamelCase)で命名する。他の種類の命名よりも自由に短縮してよい。

しかしながら一文字の名前は一時的なループ変数を除いては避けるべきである。

final で不変であってもローカル変数は定数とは見なされないので、定数の様な命名は避けるべきである。

5.2.8 型変数名

型変数名は以下の2つのやり方のうちいずれかで命名される。

5.3 キャメルケースの定義

"IPv6"や、"iOS"のような頭字語や見慣れない構造物が含まれている場合に、英語のフレーズをキャメルケースに変換する合理的な方法は一つではない。結果をより予期しやすいものにするため、Google Styleでは以下のように(ほぼ)決定的な方法を定義する。

名前の通常の形から始めて、

  1. 言葉を素のASCIIに変換し、アポストロフィを除去する。例えば、"Müller’s algorithm" は “Muellers algorithm”に変換される。
  2. これを単語に分割する。つまり、スペースや残っている句読点、ハイフンで分離する。
  3. (頭字語を含めて)すべてを小文字にする。そして…
  4. 最後に、すべての単語を1個の識別子として連結する。

元々の大文字小文字はほぼ無視される。例えば、

元々の形 正しい変換例 誤った変換例
XML HTTP request” XmlHttpRequest XMLHTTPRequest
“new customer ID” newCustomerId newCustomerID
“inner stopwatch” innerStopwatch innerStopWatch
“supports IPv6 on iOS?” supportsIpv6OnIos supportsIPv6OnIOS
“YouTube importer” YouTubeImporter
YoutubeImporter 1

1 やってよいが推奨されない。

注釈: いくつかの単語は英語では曖昧にハイフン付けされる。例えば、"nonempty" と “non-empty” はどちらも正しい。よって、 checkNonemptycheckNonEmpty というメソッド名はどちらも正しい。

6 プログラミングの実践

6.1 @Override を常に使う。

メソッドに @Overrideアノテーションを付けるのが正当な場合は、常に使用する。これは親クラスのメソッドをオーバーライドするクラスメソッドや、インターフェースのメソッドを実装するクラスのメソッドや、親インターフェースのメソッドを再定義する子インターフェースのメソッドも含む。

例外: @Override は親メソッドが@Deprecated の場合書かなくても良い。

6.2 キャッチした例外を無視しない

以下の例外を除き、キャッチした例外に対してなにも対応しないのが正しいことはめったにない。大抵の対応はログを取るか、ありえない場合ならば AssertionError として再スローするかである。

キャッチ節でなにもしないことが本当に適切であるならば、それを正当化する理由をコメントで説明する。

try {
  int i = Integer.parseInt(response);
  return handleNumericResponse(i);
} catch (NumberFormatException ok) {
  // 数字ではない。構わん、続けるだけだ。
}
return handleTextResponse(response);

例外: テストにおいて例外がスローされることを期待する場合はキャッチした例外は、変数名にexpectedと命名されているのであれば、コメントなしでキャッチしたまま無視してよい。以下の例はテスト対象のメソッドが期待した型の例外をスローすることを確認するためのよくあるイディオムで、コメントは不要である。

try {
  emptyStack.pop();
  fail();
} catch (NoSuchElementException expected) {
}

6.3 staticなメンバーはクラスを使って修飾する。

staticなメンバーへを使う場合はクラス名経由で使う。そのクラスの変数や式経由で使ってはならない。

Foo aFoo = ...;
Foo.aStaticMethod(); // 良い
aFoo.aStaticMethod(); // 悪い
somethingThatYieldsAFoo().aStaticMethod(); // とても悪い

6.4 ファイナライザは使わない。

Object クラスの finalize() メソッドをオーバーライドするケースは非常に稀である。

TIP: ファイナライザは使うな。どうしても使う必要があるというなら、まず Effective Java の項目7「ファイナライザを避ける」を必ず読み、理解し、 その上で ファイナライザは使うな。
(訳注:特にリソースの解放をファイナライザでやろうとすると、およそ期待通りには動作しないことが知られている。詳細は本文にもある通りEffective Javaを読むべし。)

7 Javadoc

7.1 フォーマット

7.1.1 一般的なフォーマット

Javadocブロックの基本的なフォーマットは以下の例の通り。

/**
 * 複数行のJavadocテキストはここに書かれる。
 * 普通に改行される。
 */
public int method(String p1) { ... }

一行の例は以下の通り。

/** 特に短いJavadoc */

基本的な形は常に使ってよい。 Javadocタグがない場合やコメントマーカを含めたJavadocブロック全体において1行で書くほうが体裁が良い場合に限って一行の例のような書き方が許される。

7.1.2 段落

一つの空行つまり行頭のアスタリスク(*)のみの行が段落と段落の間に挿入される。もしjavadocタググループがあるならばその前にも挿入される。最初以外のすべての段落には、最初の単語の前に空白無しで <p> が入れられる。

7.1.3 javadoc タグ 2

標準のjavadoc タグで使われるものは param, @return, @throws, @deprecatedの順で現れる。これらの4つには記述が必ずつかなくてはならない。javadoc タグが1行コメントに収まらない場合、2行目以降は@の位置からスペース4個以上インデントされる。

2 訳注:javadoc での @param といった節のこと。原文では"at-clauses"であるが、GoogleJavaStyleでしか使っていない用語なのでjavadocの元文書に基づきjavadoc タグと翻訳した。参照 javadoc タグ

7.2 要約の記述

クラスとメンバーのJavadocは簡単な 要約の記述 から始める。この記述はとても重要だ。なぜならクラスやメソッドの索引のような特別な場所に現れる唯一のテキストだからである。

この記述は小さな断片の形である。つまり名詞句か動詞句であって、完全な文章であってはならない。「このクラス {@code Foo} は、、、」とか「このメソッドはナニナニを返す。」で始まってはならないし、「結果を保存しなさい。」という命令形でもいけない。しかしながら、この断片はあたかも文であるかのように大文字から初めて書き、句読点を付ける。

TIP: /** @return 顧客ID */ といった簡単なJavadocを書くことはよくある間違いである。これは間違いで正しくは以下のように直されるべきである。 /** 顧客IDを返す。 */

7.3 Javadocが使われる場所

少なくとも、 public なクラスとそのクラスの public protected なメンバーにはjavadocを書くこと。但し後述の例外が有る。

クラスとメンバー以外にもJavadocは必要に応じて書く。クラス、メソッド、フィールドの全体の振る舞いや目的を記述するのに実装コメントが使われている場合は、代わりにJavadocに置き換える。(より統一的で、ツールとの親和性も高い。)

7.3.1 例外 自己叙述的なメソッド

javadocは getFoo のような簡単で明確なメソッドの場合は任意とする。つまり、「fooを返す」以外の意味ある情報が本当に無い場合である。

Tip: 重要: 典型的な読者が知りたがるような関連情報を省略することを正当化するためにこの例外を引用するのは適切ではない。例えば、「getCanonicalName」というメソッドにおいて典型的な読者が「canonical name」という語の意味を知らないかもしれない場合、(単に /** canonical nameを返す。 */ と書くだけであるという理由で)省略してはならない。(訳注:おそらく、getCanonicalNameメソッドは「正規化名」を返すメソッドなのだろうが、何を持って正規化していると言えるのかは、処理の文脈によって変化する可能性が高く、多くの場合は自明ではない。よって、これはJavaDocを省くべきでない例にあたる)

7.3.2 例外:オーバーライドするメソッド

親クラスのメソッドをオーバーライドするメソッドについてはJavadocは必須ではない。