たなかの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

Javadoc②

前回、Javadocについてを簡単にですがまとめました。
軽く復習すると、
Javadocとは、クラスやメソッドを利用する人向けのドキュメントであること
・クラスや『メンバー』(フィールドとメソッドをまとめてこう呼ぶ)に対しての説明を書く場合にのみ使用すること
Javadocからクラスやメソッドの仕様などが読み取れること
などを学びました。

今回は実際にブラウザでJavadocを確認したり、読み取りを行いたいと思います。

 

■標準APIJavadocの確認方法
Javaアプリ開発をする中で、一番確認するJavadocは恐らく標準APIJavadocと書籍にありました。
標準APIJavadocは「クラス名 javadoc」と検索すると、
古いバージョンがヒットすることも多いで、ブックマークとして以下に貼り付けておきます。

Java SE 日本語ドキュメント(バージョンごと)
https://www.oracle.com/jp/java/technologies/documentation.html
確認したいバージョンの「日本語」のリンクをクリックすると、バージョン個別のトップページに遷移します。

JDK 17ドキュメント
https://docs.oracle.com/javase/jp/17/index.html
先ほどのページで確認したいバージョン(例えば、17)の「日本語」をクリックした遷移先のページです。
様々なリンクがありますが、左側のナビゲーションメニューから「APIドキュメント」をクリックするとJavadocを開くことができます。

JDK 17 Javadocのトップページ
https://docs.oracle.com/javase/jp/17/docs/api/index.html

 

Javadocの着目すべき点
JDK 17 Javadocのトップページへ行くと情報量が非常に多くどこを読めばいいかわかりません。
ここで着目すべき点はクラスとメソッドの説明です。

 

■例:「Listインターフェース」の「addメソッド」を呼び出す際に引数にnullを渡しても良いのかを確認する
確認手順は以下の通りです。
①まず、「Listインターフェース」のJavadocを確認します。
今回探したいListインターフェースは正確には「java.util.List」になります。
java.utilパッケージのListクラスという意味です。
この「java.util.List」を以下のページ内右上の検索フィールドに入力しエンターを押します。
https://docs.oracle.com/javase/jp/17/docs/api/index.html
これで「Listインターフェース」のJavadocが表示されました。

 

②クラスやインターフェースのJavadocの先頭で3つを確認する
クラスやインターフェースのJavadocの先頭で特に注目するのは以下3点です。

継承関係
スーパークラスやサブクラスを確認することで、どのクラス/インターフェースにキャストができるのか、
どの型の変数や引数に渡すことができるのかを確認できます。
今回ですと、すべてのスーパー・インターフェース/「Collection<E>」,「 Iterable<E>」とあります。
ここから、Iterableインターフェース ➡継承➡ Collectionインターフェース ➡継承➡ Listインターフェース
となっていることが分かります。要はListインターフェースの全親インターフェースがわかるということです。
https://workteria.forward-soft.co.jp/blog/detail/10082#anchor_1

★実装インターフェース
実装しているインターフェースを見ることで、そのクラス(インターフェース)がどのような役割を持っているのかを確認することができます。
Listインターフェースの場合は「既知のすべての実装クラス:」が表示されています。
例えば、「ArrayList」などがどのような役割を持つのかをクリックし確認することができます。
また、その下には「public interface List<E> extends Collection<E>」から始まるところから
このクラスについての説明があります。

★導入されたバージョン
今回はJava 17ですが、プロジェクトの環境によってはJava 8やJava 11など古いバージョンを使うことも多くあります。
見ているクラスやメソッドが、使っているJavaバージョンで利用可能なのかを確認する必要があります。

 

③addメソッドの説明を見る
先ほどの導入されたバージョンから下にスクロールを進めると「メソッドの詳細」の箇所に到達します。
そこにaddメソッドの説明が記載されています。
早速見てみると「例外」の項には、addメソッドで投げられる可能性のある例外が記述されています。

例外:「NullPointerException - 指定された要素がnullで、このリストがnull要素を許可しない場合」
※nullとは、変数がどこも参照していないことを示す値です。要は空です。
変数がどこも参照していないのに、参照先のメソッドを呼び出そうとすると、
"NullPointerException"が発生します。

上記の情報からListインターフェースの仕様として、addメソッドにnullを渡した場合、
実装クラスによっては例外である”NullPointerException”が投げられる可能性があることが分かりました。
では、Listの実装で良く使うArrayListはどうなっているのかを確認してみます。
Java.util.Listと同様java.util.ArrayListJavadocを開き、addメソッドの欄までスクロールします。

https://docs.oracle.com/javase/jp/8/docs/api/java/util/ArrayList.html

ArrayListのaddメソッドのJavadocには例外を投げるケースが記載されていません。
ここから、ArrayListはnullを許容する実装であり、addメソッドにnullを渡しても
例外”NullPointerException”は投げられないことがわかりました。
なお、ArrayListクラス自体の説明序盤でもnullを許容する実装であることが明記されています。

以下抜粋:
Listインタフェースのサイズ変更可能な配列の実装です。
リストのオプションの操作をすべて実装し、nullを含むすべての要素を許容します。

※ここまでは日本語版Javadocを見てきましたが、日本語場はあくまで参考用の為、
機械翻訳した上で適宜人間が修正を加えたものになります。
英語に抵抗があってもゆくゆくは英語版を読めるのが好ましいとの事です。
また、Oracle社による日本語版の標準APIJavadocでは、文章にマウスカーソルを重ねると英語の原文を表示することができます。
がしかし、先ほどやってみましたができませんでした。後で調べます。

 

ちなみに、「すべてのスーパー・インターフェース」の上には、「型パラメータ:」の記載があります。
(型パラメータは"型変数"や"仮型パラメータ"などとも呼ばれているようです。)
ここには「指定する型などの情報」が記載されています。
なぜこんな曖昧な表記の仕方なのかいうと、インターフェースを作成する際など、具体的な型などが決まっていないからです。
そのような時に、型パラメータが使用されるというわけです。
ただListでは<E>となっていますが、なんでもいいわけではなく決まりがあります。
例えば、<E>はElementの頭文字で「要素」を表しています。
なので、Listインタフェースでは、「E - このリスト内に存在する要素の型」との記載があるわけです。
List内の要素が文字列であればStringとなり、以下のように使用します。
List<String> obj = new ArrayList<String>();
注意点としては、型変数<E>に指定できるのは参照型のみで、基本型は使えません。
List<int>とは書けず、ラッパークラスを使用してList<Integer>とする必要があります。
参考:https://programmer-life.work/java/generics-type
https://so-zou.jp/software/tech/programming/java/generic/#:~:text=%E5%9E%8B%E5%A4%89%E6%95%B0%20(type%20variable)%E3%80%8C,%E5%90%8D%E5%89%8D%E3%81%8C%E4%BD%BF%E7%94%A8%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

 

IntelliJ IDEAからJavadocを見る
IDEを使っていればブラウザを開かなくてもJavadocを確認できます。
確認したいクラス名やメソッド名テキストカーソルを合わせた状態で、
[Ctrl]+[Q]を押すとエディタ内のポップアップウィンドウでJavadocを表示できます。
もう一度[Ctrl]+[Q]を押すとドキュメントツールウィンドウが現れ、
テキストカーソル位置のJavadocを常時自動的に表示してくれるようになります。
慣れないAPIやライブラリを利用するときに使用するといいです。

 

EclipseからJavadocを見る
Eclipseの場合は対象クラスやメンバー(フィールドとメソッドをまとめた呼び方)の名前をcursor hoverすると表示されます。
 「@author」など色んな注釈が用意されており、Eclipseの場合、javadocコメント内でctrl+spaceで一覧が表示されます。
アノテーションについては次回まとめます。

 

これでJavadocから必要な情報を読み取れるようになりました。
次回は実際にJavadocを書くことについてまとめます。

Javadoc①

プロジェクト作成&JRE(JDK)選択編が完了しました。

作成したプロジェクトにpackageやclassを追加していくことになるのですが、
その前にコメントについて学ぼうと思います。

 

■コメントとは・・・
コメントとは、プログラムのそばに「どのような処理をするのか」の情報を記載したものになります。
コメントは記載方法が3つありますが、いずれもプログラムの動作に影響はありません。
また、コンパイル時には無視されるので、classファイルには残りません。
コンパイルとは、ソースファイル(.java)をクラスファイル(.class)に変換することです。
コンピュータが実行しやすい形に変換するのでclassファイルの中身はバイトコードです。
また、コンパイルする際に使用するソフトウェアを「コンパイラ」といい、
ソースコードの文法チェックを行い、誤りがあればコンパイルが失敗します。

 

コメントアウトの種類

1、
// これは「1行コメント」や「行末コメント」と言います
 ⇒「ctrl+/」で対象行をコメントアウトするが効率的
 (複数行選択して一気にコメントアウト可能)

2、
/*
これは「複数行コメント」や「ブロックコメント」と言います
開始から終了までの間、何行書いても、コメント扱いになります
*/

3、
/**
これは「Javadocコメント」という特別なコメントです
 */

 

/**
*  このように書く場合が多いです
*
 */

 

1と2の記載内容には特に決まりごとは無く自由なコメントが可能となっています。
とはいえ、実際の現場ではプログラムの内部実装を確認する人に向けたものであることが多いです。
ただ、3の「Javadocコメント」にはルールがありますので以下にまとめようと思います。


Javadocとは・・・
Javadocとは、クラスやメソッドを利用する人向けのドキュメントです。

 

Javadocのドキュメント化
クラスやメソッドを利用する人向けのドキュメントなので、もちろんドキュメントとして生成することができます。
具体的には、プログラムに埋め込まれたJavadocコメントはjavadocコマンドでHTML形式に変換されブラウザで見るといった感じです。
ただ、コマンドと言うくらいなのでオプションが色々あります。ここでは詳しく触れません。

 

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

 

Javadocから読み取れること
・クラスやメソッドの仕様
・どのような引数を渡すべきなのか
・どのような状況で例外が発生するのか
・クラスやメソッドが導入されたバージョン
など・・・

 

Javadocを書く場所

classや『メンバー』(member)(fieldとmethodをまとめてこう呼ぶ)に対しての説明を書く場合にのみ使用すること。

クラスやメソッドを利用する人向けに書くので当たり前です。
Javadocを生成したときにこのコメントが採用されます。

Eclipseの場合は対象classやmemberの名前をcursor hoverすると表示される)
 「@author」など色んな注釈が用意されている(Eclipseの場合、javadocコメント内でctrl+spaceで一覧が表示される)。

 

次回は続きをまとめます。

プロジェクト作成&JRE(JDK)選択編

リスタート1日目は、Java復習をします(n回目...)

プロジェクト作成&JRE(JDK)選択編です。

 

■まず初めにプロジェクトを作成する
Java言語を使用して個人開発をするとなったら最初にプロジェクトを作成しなければなりません。
また、作成するにあたりプロジェクト名は自分で考える必要があります。

ここで抑えるポイントは以下4つです。
1、命名規則については、言語仕様上は殆ど制約なし
2、半角記号の\/*"|<>?と末尾.はダメ
 ⇒結局のところプロジェクトはOSのフォルダで管理するため、フォルダ名に使用できないものは当然不可となる。
3、日本語とかはやめておくのが無難
4、慣習としては「大文字は使わない」というものがある

 (Javaの標準APIには大文字を使ったpackage名はない)
 ⇒が、現場によっては大文字を使ってる所も結構あるとのこと。

 

■次に使用するJRE(JDK)を選択します
ここでは使用しているIDEによって選択肢が変わります。

EclipseJREを選択する
IntelliJ IDEA⇒JDKを選択する

そもそも、JREJDKは何が違うんだという話ですが、
以下のようにバージョンによって中身が変わるらしいです。

 

Java 8まで
JRE(Java SE Runtime Environment) = Java VM + API + Applet/Java Web Start
JDK = Java VM + API + JRE + 開発ツール(javac等)
(JavaVM, APIは二重に含まれていた)

Java 11以降
JRE = Java VM + API
JDK = JRE + 開発ツール

※このあたりは実際のところOracleも雑に扱っているらしく、
はっきりとした定義は難しいとの意見もあります。
なので、初学者である私にはまだ難しいと判断し、今回は深掘りはしません。
別途、ディストリビューションなどと絡めて用語の意味まではまとめようと思います。

 

さて、使用するJRE(JDK)を選択する話でしたが、
簡単に言うと、どのバージョンのJavaを使うのかを選択しましょうということです。
基本的には最新バージョンを使うで問題ありません。
最新のを使うのがlibraryも充実してるので良いのと、
JVMも進化してるので、最新になるほど処理が速いというメリットがあります。

 

■その他の細かい設定が不要ならば「完了」や「作成」ボタンを押す
細かい設定とは「Maven プロジェクト」や「Gradle プロジェクト」などです。
ここで「Maven プロジェクト」や「Gradle プロジェクト」を選択するとMavenやGradleが使えるprojectを作成できます。
ビルドツールについては、またの機会にまとめます。

ここでは設定をしませんが後から、作成したprojectを右クリックして「プロパティー」から設定を色々と変更できます(Eclipseの場合)
IntelliJ IDEAの場合も、作成したprojectを右クリックして「フレームワークサポートの追加」から設定を色々と変更できます。
https://pleiades.io/help/idea/convert-a-regular-project-into-a-maven-project.html

最初にプロジェクトを作ってしまえば、後はその中にpackageやclassをどんどん追加していくだけです!

 

基本的には、この「プロジェクトという単位」が「アプリケーションの単位」になります。
つまり、Windowsツールを1つ作成したい場合は、それで1つのプロジェクトを作成し、
さらに、Webアプリ(ECサイトなど)を1つ作成したいとなれば、また別に1つのプロジェクトを作成することになるということです。
前半に書きましたが、OSのフォルダ・システム上では、プロジェクトはフォルダとして作成されます。
Eclipseでプロジェクトを作成した場合には、このフォルダに「.project」というファイルが作成されるが、
このファイルが置かれたフォルダをEclipseはprojectとみなしている、というカラクリです。

 

以上でプロジェクト作成&JRE(JDK)選択編は完了です。