【Java発展学習11日目】標準的な開発ツール

# Javadoc
`ソースコード → プログラム仕様書`の自動生成を行う開発ツール。

## Javadocコマンド・オプション
[参考: javadocコマンド](https://java-code.jp/49)
`ターミナル`等のコマンドラインツールで`Javadoc`を出力するコマンド・オプションは、以下の通り。

```zsh:Javadocの出力
% javadoc <オプション> <.javaファイル>
```

| オプション | 内容 |
|:--|:--|
| `-d <出力先パス>` | `Javadoc`ドキュメントの出力先を指定 |
| `-private` | `private`メンバを出力対象に加える |
| `-encoding` | `ソースコード`の文字コード |
| `-docencoding` | `Javadoc`ドキュメントの文字コード |
| `-charset` | `Javadoc`ドキュメント閲覧時の文字コード |
| `-author` | `@author`タグが付与されるクラスの**実装者**を出力 |
| `-version` | `@version`タグが付与されるクラスの**バージョン情報**を出力 |

## Javadocタグ
利用機会の多い`Javadocタグ`は、以下の通り。

| タグ | 内容 | クラス/インタフェース | フィールド | メソッド |
|:--|:--|:-:|:-:|:-:|
| `@author <実装者>` | クラスの**実装者** | o |   |   |
| `@version <バージョン番号>` | クラスの**バージョン情報** | o |   |   |
| `@param <引数名> <説明文>` | `引数`の詳細情報 |   |   | o |
| `@return <説明文>` | `戻り値`の詳細情報 |   |   | o |
| `@exception <FQCN> <説明文>` | 送出可能性のある`例外`の説明 |   |   | o |
| `@see <クラス名>` | **関連**するクラス | o | o | o |
| `@since <バージョン番号>` | 実装時の**バージョン情報** | o | o | o |
| `@deprecated <解説>` | **非推奨**である旨の明示 | o | o | o |

***

# javacコマンド
`ソースファイル → クラスファイル`の生成(=`コンパイル`)を行うコマンド。

`-Xlint`オプションを用いることで、ソースコードの軽度な不備(=**警告**)をコンソールに出力することができる。

```zsh:ソースファイルのコンパイル
% javac <オプション> <ソースファイル>
```

## アナテイション
`クラス`・`インタフェース`やその`メンバ`に対して、以下のアナテイションを付与することで、
`-Xlint`オプションを用いてコンパイルした際に出力する警告を調整することができる。

| アナテイション | 内容 |
|:--|:--|
| `@SuppressWarnings("<パラメータ>")` | 警告対象から除外 |
| `@Override` | 親クラスのメソッドとのスペルチェック |
| `@Deprecated` | **非推奨**である旨を`コンパイラ`に明示 |

### @SuppressWarningアナテイションのパラメータ
`@SuppressWarning`アナテイションで引数に指定する`パラメータ`は、以下の通り。

| パラメータ | 抑制対象 |
|:--|:--|
| `all` | **全て** |
| `serial` | `シリアルバージョンUID` |
| `cast` | 不要な`キャスト` |
| `unchecked` | **代入チェック**のない`キャスト` |

***

# jarコマンド
`クラスファイル -> JARファイル`の自動生成を行うコマンド。

なお、`JARファイル`の生成時には`マニフェストファイル(=.mfファイル)`が自動で生成される。

```zsh:jarコマンド
# JARファイルの生成
% jar -cvf <JARファイル名> <クラスファイルが含まれるディレクトリパス>

# 独自のマニフェストファイルを格納したJARファイルの生成
% jar -cvfm <JARファイル名> <マニフェストファイル名> <クラスファイルが含まれるディレクトリパス>

# JARファイルの展開
% jar -xvf <JARファイル名>

# JARファイルの閲覧
% jar -tvf <JARファイル名>
```

## マニフェストファイルの属性(エントリ)
`マニフェストファイル`に含まれる主なエントリは、以下の通り。

| エントリ | 内容 |
|:--|:--|
| `Manifest-Version` | マニフェストファイルの`バージョン番号` |
| `Created-By` | マニフェストファイルを生成した`Java`に関する情報 |
| `Class-Path` | 参照ライブラリの`相対パス` |
| `Main-Class` | `main`メソッドを含む`メインクラス`の完全限定名(= `FQCN`) |
| `Automatic-Module-Name` | モジュール名 |

なお、`Main-Class`属性を指定することで、`JARファイル`の実行時に`メインクラス`の指定が不要となり、
一部のOSで「**ダブルクリック**」による`JARファイル`の起動が可能となる。

***

# javaコマンド
`クラスファイル`または`JARファイル`のメインクラスを実行するコマンド。

```zsh:Javaの実行
# メインクラスを含むJARファイルの起動(Main-Class属性に記述がない場合)
% java -cp <JARファイル名> <メインクラスのFQCN>

# メインクラスを含むJARファイルの起動(Main-Class属性に記述がある場合)
% java -jar <JARファイル名>

# ガベージコレクションの発生毎に情報を出力
% java -verbose:gc <メインクラスのFQCN>

# JVMへの割り当てメモリ容量を指定して実行
% java -Xms<最小割当量> -Xmx<最大割当量> <メインクラスのFQCN>
```

# 2種類のメモリ領域(スタック/ヒープ)とガベージコレクション
[参考: Javaにおける参照の仕組み](https://qiita.com/dung717/items/6552005a4fdccc893c43)
`参照型オブジェクト`の**変数名**および`値型(=プリミティブ型)データ`の**変数名と値**は`スタック領域(stack)`で保持され、
`参照型オブジェクト`の**値**や`値型データを保持する配列`の**値**は`ヒープ領域(heap)`で保持される。

一般的に`ヒープ領域`の方が`スタック領域`よりも大量に消費され、
空きメモリが少なくなると`JVM`内部で動作する`ガベージコレクタ`によって`ガベージコレクション`が行われる。

また、`ガベージコレクション`の実行時は`Object`クラスの`finalize()`メソッド(=`ファイナライザ(finalizer)`)が呼び出され、
`ヒープ領域`の解放処理が終了するまで**他の処理が中断**される。

この仕様により、長期稼働するプログラムでは`メモリリーク(memory leak)`が発生し、処理が一向に実行されない`フリーズ状態`に陥る可能性がある。

***

# JShell
`Java`を対話的に実行できる開発ツール。`jshell`コマンドによって起動することができる。

## サンプルコード

```zsh:JShellによるJavaの実行
% jshell
|  JShellへようこそ -- バージョン16.0.1
|  概要については、次を入力してください: /help intro

jshell> int a = 10
a ==> 10

jshell> if (a >= 10) {
   ...>     a++;
   ...> }

jshell> System.out.println(a);
11
```

***

# ビルドの自動化ツール

| ビルドツール | 内容 |
|:--|:--|
| バッチファイル(batch file) | `Windows`で利用される、ビルドコマンドを列挙することで順次実行を行うファイル |
| シェルスクリプト(shell script) | `macOS`や`Linux`で利用される、ビルドコマンドを列挙することで順次実行を行うファイル |
| `Apache Ant` | `build.xml`ファイルによってビルド手順を定めるツール |
| `Apache Maven` | プロジェクトの各種情報を記述する`pom.xml`と標準フォルダ構造に沿って<br>`Maven標準コマンド`を実行することでビルドを自動化するツール |

## Maven
[参考: Maven Tips](https://www.techscore.com/tech/Java/ApacheJakarta/Maven/7/)
`Mavenプロジェクト`に関する情報を記述する`POM(project object model)`と、
ファイルの種類毎に格納場所が定められた`標準フォルダ構造`に従って、
`Maven標準コマンド`を実行することでビルドが行われる。

### POM
`XML`で記述された`POM`のタグ(属性)は、以下の通り。

| タグ | 内容 |
|:--|:--|
| `<project>` | `Mavenプロジェクト`の各属性の親タグ |
| `<modelVersion>` | `POMモデル`のバージョン情報 |
| `<groupId>` | `Mavenプロジェクト`の作成者の識別ID |
| `<artifactId>` | `Mavenプロジェクト`の識別ID |
| `<version>` | `プログラム`のバージョン情報 |
| `<properties>` | `POMファイル`で利用する各種プロパティ(属性)の親タグ |
| `<dependencies>` | プログラムが利用する`依存ライブラリ`(=`<dependency>`タグ)の親タグ |
| `<dependency>` | `依存ライブラリ`毎に設定する各種プロパティ(属性)の親タグ |
| `<scope>` | `依存ライブラリ`の適用範囲(スコープ) |

### 標準フォルダ構造
`Maven`が定めるフォルダ構造は、以下の通り。

![プロジェクトフォルダ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673880/65066afb-f744-07a5-bcaa-003e557e4694.png)

また、`src`フォルダ内の配置図は以下の通り。

![srcフォルダ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673880/d84cc565-952e-9b60-1dd2-96620f5ac6e5.png)

### Maven標準コマンド

```zsh:Mavenのインストール〜Mavenコマンドの実行
# Homebrewを通じたMavenのインストール
% brew install maven

# Mavenのバージョン情報の出力
% mvn --version
Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
...

# Mavenプロジェクトのコンパイル
% mvn compile

# MavenプロジェクトのJARファイルを生成
% mvn package

# MavenプロジェクトのJavadocの生成
% mvn javadoc:javadoc

# Mavenプロジェクトの公開用Webサイトの生成
% mvn site

# Mavenプロジェクトの一時ファイル(targetフォルダ)を削除
% mvn clean
```

***

# 用語集

| 用語 | 内容 |
|:--|:--|
| マニフェストファイル(manifest file) | `JARファイル`に含まれる、各クラスファイルの説明文を表すテキストファイル。 |
| ガベージコレクション(GC; Garbage Collection) | `ヒープ領域`の圧迫時に、どの変数にも参照されないインスタンスを解放すること。 |
| メモリリーク(memory leak) | **プログラムの不備**によって生じる、ガベージコレクション対象が解放されない現象。 |
| インタプリタ言語(interpreter language) | `Python`や`JavaScript`で採用される、ソースコードを1行ずつ変換・実行する言語。 |
| コンパイル言語(compile language) | `Java`などで採用される、ソースファイル全体を読み込んでから変換・実行する言語。 |
| REPL(read-eval-print-loop) | ソースコードを対話的に実行できる開発ツールの総称。 |
| 完全限定成果物名(FQAN; fully-qualified artifact name) | `グループID`・`アーティファクトID`・`バージョン番号`の3つを<br>`:(コロン)`で連結することで一意なプログラムとした命名規則。 |
| セマンティックバージョニング(semantic versioning) | `バージョン番号`を<br>`<メジャーバージョン>.<マイナーバージョン>.<パッチバージョン>`<br>で表す採番方法。 |
| モジュール(module) | `パッケージ`の集約単位。 |