たなかのJava日記

どんなことをやったか(学んだか)、どこで詰まったか(わからなかったか)、どこで工夫したかの記録です。

Javadoc③

Javadocは、標準APIやライブラリの利用方法を確認するのに便利です。
しかし、自分作成したコードはもちろん調べることができません(当たり前ですが、、、)
そのため、自分で書いたコードを正しく使ってもらうためには、自分のコードにJavadocを書く必要があるのです。
なお、”コードを正しく使ってもらう”メリットは以下になります。

1、Javadocを読んでもらえれば、自分のコード(クラスやメソッド)を利用する人が実装を見なくても、使い方を理解してもらえるようになること。
 例えば、きっと例外はでないだろうといった憶測で利用されることがなくなります。
 これにより思わぬバグ等を防ぐことに繋がります。
2、Javadocを読むことで、以下を事前に確認することができる。
 ・どのような場合に例外が発生するのか、
 ・引数にnullを渡すことが許されるのか、
 など・・・

今回はサッカーワールドカップが近いこともあり、
「渡された年がサッカーワールドカップ開催年」
であるかどうかをを調べるメソッドを例にJavadocを書いてみます。

    public boolean isSoccerWorldCupYear(int year) throws IllegalArgumentException {
        if (2026 < year) {
            throw new IllegalArgumentException("2026年までサポートしています。入力" + year);
        }
        return year % 4 == 2;
    }

このコードでは、次回開催の2026年までをサポートしています。
サッカーワールドカップは必ずしも4年に一度開催されているわけではないので、この実装にはバグがあります。
(恐らく中止とかもあるので)
せっかくなので次回、自動テストを書いて修正したいと思います。

まず、Javadocを書くにあたり今回作成したメソッドが何をしているのか確認をします。
引数はint型で西暦を渡すと、サッカーワールドカップイヤーどうかをboolean型で返すことがわかります。
しかし、どのような条件で例外"IllegalArgumentException"が投げらるのかは、メソッド内の実装を見ないとわからない状態です。
自分のコード(クラスやメソッド)を利用する人が実装を見なくても、
使い方を理解してもらえるようになることがJavadoc目的なので例外を含めた仕様を明記します。

では、仕様の明記の仕方はどうするのでしょうか。
IntelliJ IDEAでは簡単です。

メソッド定義の前の行で「/**」と入力して「Enter」キーを押すだけです。
Eclipseではメソッド定義の前の行で『Alt + Shift + J』

//Javadoc記載前
    public boolean isSoccerWorldCupYear(int year) throws IllegalArgumentException {
        if (2026 < year) {
            throw new IllegalArgumentException("2026年までサポートしています。入力" + year);
        }
        return year % 4 == 2;
    }
//メソッド定義前の行で「/**」と入力して「Enter」キーを押下後
    /**
     * 
     * @param year 
     * @return 
     * @throws IllegalArgumentException 
     */
    public boolean isSoccerWorldCupYear(int year) throws IllegalArgumentException {
        if (2026 < year) {
            throw new IllegalArgumentException("2026年までサポートしています。入力" + year);
        }
        return year % 4 == 2;
    }

メソッドのシグネチャ(メソッド名、引数の個数やその並び順の情報をまとめた呼び方)から
必要と判断できるタグは勝手に生成してくれます。
ただ、説明が記載されていませんので、自動生成直後は「記載してくださいよ~」と
警告で黄色くハイライトされています。

今回は、
・メソッド(Javadocコメント先頭)
・パラメータ(@param)
・戻り値(@return)
・例外(@throws)
の説明をタグの後に記載し完成させると、警告は消えます。

次にタグの説明に何を書くのかですが、以下にまとめました。
@param、どのような値を渡すべきか、値が取り得る範囲など
@return、どのような時にどのような値を返すのか、nullを返す条件など
@throws、どのような時に例外が発生するのか


その他、必要に応じてタグは追加してください。
・開発者名(@author)
・クラスやメソッドを実装したバージョン(@since)
などがあります。

//Javadoc記載後
    /**
     * 渡された西暦年がサッカーワールドカップ開催都市であるかどうかを判定する
     * @param year 西暦
     * @return サッカーワールドカップ開催都市であればture
     * @throws IllegalArgumentException まだオリンピック開催が確定していない年を渡した場合
     */
    public boolean isSoccerWorldCupYear(int year) throws IllegalArgumentException {
        if (2026 < year) {
            throw new IllegalArgumentException("2026年までサポートしています。入力" + year);
        }
        return year % 4 == 2;
    }

これで、isSoccerWorldCupYearメソッドを使う人は、コードを見なくても
[Ctrl]+[Q]で仕様を確認できるようになりました。
もう一度、[Ctrl]+[Q]を押せば常時表示してくれます(IntelliJ IDEAの場合)

補足として、
クラスやコンストラクタにも同様にJavadocを書くことができます。
というか、恐らく書かないといけないです。
メソッドと違うところは、使えるタグの種類が異なります。
考えてみればわかると思いますが、クラスの定義に引数や戻り値は無いので、
@paramや@return は使えません。

Javadocで使えるタグ(すべて記載しているわけではありません)
クラスに使用可能なタグ
・説明の記載可、@since
フィールドに使用可能なタグ
・説明の記載可、@since
コンストラク
・説明の記載可、@param、@throws、@since
メソッド
・説明の記載可、@param、@throws、@return、@since

最後にJavadocのHTMLを生成してみましょう。
今回書いたJavadocを含めたプロジェクトのHTMLを作成したい場合は、
Mavenjavadoc:javadoc Goalを使用します。

IntelliJ IDEAの場合は[Ctrl]キーを2回を押し、「mvn javdoc:javadoc」と入力して、
「Enter」キーを押下するだけです。

コンソールが動き始め、「プロセスは終了コード 0 で終了しました」と表示されたら生成完了です。
IntelliJ IDEAの場合はtarget/site/apidocs配下に[index.html]として生成されています。


Eclipseの場合は以下サイトの中盤を参考
https://workteria.forward-soft.co.jp/blog/detail/10144