「プロになるJava」を読んで

# 概要
[「プロになるJava」](https://gihyo.jp/book/2022/978-4-297-12685-8)を読みましたので、各部ごとのアウトプットを兼ねて記します。

# 第一部　Javaを始める準備
### Javaとは
Javaとは、プログラミング言語であるJava言語と実行環境であるJVMを中心としてプログラミング技術を指す。

### JVMとは
Java仮想マシンのこと。コードを読み込んで実行する役割を持つ。

### JDK
Javaのプログラムを開発するために必要なソフトウェアパッケージで、Java Development Kitの略。
JVMもJDKに含まれる。

#### Java SE
Javaでどのようにプログラムをかけるか、どのように動作するか、といった仕様のこと。

### 開発環境の準備
1. Oracle JDKのインストール
2. IDEのインストール　本書ではIntelliJ IDEAを使用します。

# 第2部　Javaの基本
### Jshell
JShell=Javaのプログラムを1行ずつ実行できるコマンドラインツール

### 演算
Javaにおける主な算術演算子は下記となります。
| 演算子 |  説明|
|:-----:|:----:|
|+      |足し算 |
|-      |引き算 |
|*      |掛け算 |
|/      |割り算 |
|%      |余り   |

### 文字列リテラル
文字列は"（ダブルクォーテーション）で囲む。
リテラルとは、コード中に埋め込む値のこと。

### 文字列の連結
文字列の連結は+演算子を使う。
```Java
>"test" + "er"
==> "tester"
```
+演算子の左右どちらか文字列の場合は文字列の連結が行われる。
```Java
>"test" + 12 + 3
==>"test123"
```
### メソッドの呼び出し
メソッドは処理をまとめて名前をつけたもの。
```Java
>"test".toUpperCase()
==>"TEST"
```
toUpperCaseメソッド：大文字に変換する
```Java:メソッド呼び出し構文
値.メソッド名()
```

### 文字列のフォーマット
formattedメソッドを使う
```Java
>"test%s".formatted(12+3)
==>"test15"
```
%sの部分が、formattedメソッドに渡した引数の値で置き換えられる。
%sの部分を**書式指定子**と呼ぶ。
上記では%sと記したが、数値に対しては%dを使う方が望ましい。
%dを使うことで、数値ならではの形式を指定できる。
例えば%,dとすると、3桁ごとにカンマが入る。

### 変数
変数の宣言は下記のように行う。
```Java:変数の宣言構文
var 変数名 = 値
```

### 型
varを使って変数を宣言したときには、値の種類＝型が決まる。
| 型 | 値の種類 | 実際の値 |
|:-:|:-:|:-:|
|int   |整数   |0, 10, 400   |
|double   |実数   |1.414, 0.0, 3.14   |
|boolean   |論理値   |true, false   |
|char   |文字   |'t', 'あ'   |
|String   |文字列   |"test"   |

int型やdouble型など小文字で始まっている型を **基本型（プリミティブ型）** と呼ぶ。
一方、String型は **クラス** である。
クラスはJavaで機能をまとめるための基本的な仕組みのことをいう。
String型のような基本型ではない型を **参照型**　という。

String型の値にはtoUpperCaseメソッドを呼び出せたように、参照型はメソッドを持つが、基本型はメソッドが無い。

尚、varが導入されたのはJava10からであり、Java8の時点では下記のように変数宣言のときに型を指定する必要がある。
```Java:型を指定した変数の宣言構文
型 整数名 = 値
例) String u = "myname"
```
### APIとライブラリ
API（Application Programming Interface）：機能をまとめて他のプログラムから呼び出せるようにした部品
ライブラリ：さまざまなAPIをまとめたもの

### staticメソッドとインスタンスメソッド
メソッドには2種類ある
```Java:staticメソッド構文
クラス名.メソッド名(引数)
例) LocalDate.now()
```
```Java:インスタンスメソッド構文
値.メソッド名(引数)
例) "test".toUpperCase()
```

### newによるオブジェクトの生成
newはクラスの値を生成するために使うキーワード
```Java:newによる値の生成構文
new クラス名(引数)
```

どのような引数が渡せるかはクラスによって決まっており、このとき呼び出される特別なメソッドを **コンストラクタ** という。

### オブジェクト
コンストラクタによって生成されるクラスの値のことを **オブジェクト** という。

# 第3部　Javaの文法
### 比較演算子
| 比較演算子 | 説明 |
|:-:|:-:|
|==   |等しい   |
|!=   |異なる   |
|<   |より小さい（等しいものを含まない）   |
|>   |より大きい（等しいものを含まない）   |
|<=   |以下（等しいものを含む）   |
|>=   |以上（等しいものを含む）   |

### 論理演算子
| 論理演算子 | 説明 |
|:-:|:-:|
| \|\|   |論理和   |
|&&   |論理積   |

### 条件演算子
条件によって値を選ぶ場合は条件演算子が使える。3項演算子とも呼ばれる。
```Java:条件演算子構文
条件 ? 条件がtrueのときの値 : 条件がfalseのときの値
```

### if分による条件分岐
```Java:if文の構文
if(条件1) {
  条件1が成り立ったときの処理
} else if(条件2) {
  条件2が成り立ったときの処理
} else {
  どの条件も成り立たなかったときの処理
}
```

### switchによる条件分岐
```Java:switch文の構文
switch(判定する値) {
  case 該当する値 -> 処理
  case 該当する別の値 -> 処理
  case 該当するさらに別の値 -> 処理
  ...
default -> どのcase句にも該当しなかったときの値
}
```

### データ構造
#### List
同じ型の値をまとめて扱うデータ構造
Listの中身は変更できないため、変更するためには変更のできるリスト=ArrayListを利用する。
```Java
>var authors = new ArrayList<String>()
==> []
```

addメソッドで要素の追加

```Java
>authors.add("yamamoto")
>authors.add("kishida")
```

確認すると以下のようになる。

```Java
>authors
==>[yamamoto, kishida]
```

### ジェネリクスによる型検査
ジェネリクス<>で型を指定すると、指定した型に対応していない値を扱おうとしたときに構文エラーになり、
その結果実行時にエラーが出ることを防ぐことができる。

また、事前に用意してあるリストを使ってArrayListを作ることで、型を省略できる。

```Java:ジェネリクスの型推論
//リストの作成
>var names = List.of("tanaka", "suzuki", "sato")
>var authors = new ArrayList<>(names)
==>[tanaka, suzuki, sato]
```

このとき、ArrayListが扱う型はnamesの型から推論されるため、
<>と省略して書ける。この<>をダイヤモンドオペレータという。

ジェネリクスには参照型を指定する必要があるため、基本型を扱いたいときは
ラッパークラスを使用する。

| 基本型 | ラッパークラス |
|:-:|:-:|
|int   |Integer   |
|double   |Double   |
|boolean   |Boolean   |
|char   |Character   |

### 配列
配列を用意するときはnewを使用する
```Java:配列の初期化構文
new 型 [ 要素数 ]
例) var scores = new int[3]
```
例では、要素数が3つのscoresという名前の配列を用意している。

また、あらかじめ要素の値を設定した配列を用意することもできる。
```Java:要素を設定した配列の初期化
new 型 [] { 要素, 要素, ...}
```

varではなく配列の型を明示するとスッキリ書ける。
```Java:変数に型を指定した、要素を設定した配列の初期化
型 [] 変数名 = { 要素, 要素, ... }
例) int[] nums  {1, 2, 3}
```

### レコード
Listや配列では同じ型の種類の値をまとめるが、レコードでは違う型の種類の値をまとめることができる。

```Java:レコードの定義構文
record レコード名 ( コンポーネントの型 コンポーネントの名前, ...) {}
例) record Exam(String name, String subject, int score) {}
```

レコードの要素をコンポーネントと呼ぶ。

レコードのデータを作るには、下記のように行う。
```java:レコードのオブジェクトの生成
new レコード名 (コンポーンエントの値, ...)
例) var e1 = new Exam("kis", "math", 80)
```

コンポーネントの値を取ってくるには、下記のようにする。
```java
>e1.name()
==> "kis"
```

Listを使用する場合と比べると、コードを見てどんな値を取ってくるのかがわかりやすいというメリットがある。

### Map
Mapはキーと値を結びつけるデータ構造である。
```java
>var fruits = Map.of("apple", "りんご", "grape", "ぶどう");
fruits ==> {grape= ぶどう, apple= りんご}
```

### イミュータブルなオブジェクト
Listのように、オブジェクトの内容を変更できないものをイミュータブル（不変）という。
オブジェクトをイミュータブルにすると想定しないデータ変更を防ぎやすくなる。

### for文
```java:for文の構文
for (初期化; 繰り返し条件; 繰り返し時の処理) {
  繰り返す処理
}
```

### while文
```java:while文の構文
while (繰り返し条件) {
  繰り返す処理
}
```
ループではcontinueとbreakを使用できる。
continue：ループ中の処理を打ち切って次のループに入る。
break：ループ全体の処理を打ち切って、次の処理に移る。

### 拡張for文
```java:拡張for文の構文
for (var 変数 : 配列やList) {
  繰り返す処理
}
```

### Stream
値の集合に対する処理を使い回す仕組みのこと。
Streamではラムダ式が多く使われる。
```java:ラムダ式の構文
受け取った値を使うための変数 -> 処理
```
Streamの処理は、値の集合からStreamを取り出す「Streamソース」、値を操作する「中間処理」、値をまとめる「終端処理」の3つに分かれる。

配列からStreamを取り出すには、Stream.ofメソッドを使う。
```java
>Stream.of("test", "hello", "world").toList()
==>[test, hello, world]
```

### メソッド
```java:メソッドの宣言構文
void メソッド名() {
  動作
}
```

voidは戻り値がないということを表す。

```java:引数のあるメソッドの定義構文
void メソッド名 (引数の型 処理中で使う変数) {
  処理
}
```

「処理中で使う変数」のことを仮引数、呼び出し時に指定する引数を実引数という。

```java:戻り値のあるメソッドの宣言構文
戻り値の型 メソッド名 (引数の型 処理中で使う変数) {
  処理
}
```

### ラムダ式
ラムダ式は名無しのメソッドと考えることができる。
下記のようなメソッドをラムダ式で表すことを考える。
```java
int twice(int x) {
  return x * 2;
}
```
戻り値の型とメソッド名を消す
```java
(int x) {
  return x * 2;
}
```
引数と処理の間を->で結ぶとラムダ式になる。
```java
(int x) -> {
  return x * 2;
}
```
1行の場合は{}とreturn、;を省略できる。
```java
(int x) -> x * 2
```
引数の型は省略
```java
(x) -> x * 2
```
引数が1つのときはカッコも省略できる。
```java
x -> x * 2
```
上記のような流れでよく見かけるラムダの形となる。

### メソッド参照
ラムダ式で受け取った引数をメソッドにそのまま渡しているものはメソッド参照にできる。
```java:ラムダ式をメソッド参照に変換
引数 -> なにか .メソッド(引数)
     ↓
なにか :: メソッド
```
引数なしで呼び出す場合もメソッド参照に置き換えることができる。
```java:インスタンスメソッド呼び出しをメソッド参照に変換
引数 -> 引数 .メソッド()
     ↓
メソッドの属するクラス名 :: メソッド
```

### 再帰
メソッドの中でそのメソッド自身を呼び出すことを **再帰** という。

# 第4部　高度なプログラミング
```java:try ~ catch構文
try {
  例外が発生するかもしれない処理
} catch (捕まえる例外1 変数) {
  例外の処理
} catch (捕まえる例外2 変数) {
  例外の処理
} finaly {
  例外が発生してもしなくても行われる処理
} ...
```
### クラス
クラスはJavaの基本になる仕組み。
すべてのコードはクラスに属する形で記述する。
クラスの要素となるものをメンバーと呼ぶ。メンバーは下記の4つ。
* コンストラクタ
* フィールド
* メソッド
* ネステッドクラス

レコードをクラスに変換する際のメソッドの定義には、publicがついている。
これはアクセス修飾子と呼ばれ、クラスやクラスのメンバーがどこから使えるかというアクセス制御を指定する。

| アクセス修飾子 | 範囲 |
|:-:|:-:|
|private|同じクラス   |
|指定なし   |同じパッケージ   |
|public   |制限なし   |
|protected   |同じパッケージか、継承したクラス   |

#### コンストラクタ
オブジェクトを生成するときに呼び出される特別なメソッドをコンストラクタという。

#### this
thisはそのオブジェクト自身を表す。

#### フィールド
オブジェクトに関する情報を保持する。
インスタンスメソッドとstaticメソッドがあるように、
インスタンスフィールドとstaticフィールドが存在する。

### インタフェース
インタフェースは複数のクラスに共通の性質を示すための仕組み。つまり、複数のクラスが同じメソッドを持っていることを示す仕組み。

### 継承
クラスの継承
```java:クラスの継承
class クラス名 extends 継承元クラス {
  クラスメンバー
}
```
継承元をスーパークラス、継承先をサブクラスという。

サブクラスはスーパークラスの一種という関係から、is-a関係という。

継承の使い方として差分プログラミングという考え方があり、処理の一部だけが違うときに、違う部分、つまり差分を書けばいいようにしようという考え方のこと。

### オブジェクト指向
オブジェクト指向の特徴として下記のものが挙げられる。
* モジュールと型の一体化
* 継承によるモジュールの分類
* 継承によって分類された中での差分プログラミング

# 第5部　ツールと開発技法
### Maven
MavenはJavaアプリケーション開発の現場で利用されているビルドツール。
画像や設定ファイルなどのリソオースをまとめたり、コンパイル済みの.classファイルやリソースをひとまとめにしたJRAファイルを作成したりといった、やや複雑な作業のことを **ビルド** という。

### Javadoc
JavadocはJavadocコメントと呼ばれる、/**から始まり*/で終わるコメント。
クラスやメソッドなどの前に記述する。
Javadocからは下記のようなことを読み取れる。
* クラスやメソッドの仕様
* どのような引数を渡すべきなのか
* どのような状況で例外が発生するのか
* クラスやメソッドが導入されたバージョン

### テスト
どのようにテストケースを書くと良いか
* 条件分岐する箇所・境界値の前後
* 異常値のテスト
* 不安な箇所
* 重要度の高い箇所
* バグが判明した箇所
* 細かい粒度のテスト
* わかりやすいテストケース名

### テスト駆動開発
テスト駆動開発とは、実装よりも先にテストを書くという手法。

# 第6部　Webアプリケーション開発
### Spring FrameworkとSpring Boot
Spring FrameworkはJavaアプリケーション開発向けのフレームワーク。目的別に開発されたさまざまなフレームワークの集合体という形で提供される。
Spring BootはSpring Frameworkの一部として提供されている代表的なフレームワークの一つ。

### MVCモデル
Webアプリケーションの中身はモデル・ビュー・コントローラの3つに分かれる。
モデル：アプリケーションで使用するデータを保持
ビュー：ユーザーによって利用されるユーザーインターフェース
コントローラ：ユーザーインターフェースから送られてくるリクエストを処理

### コントローラの作成
コントローラ作成の際は@Controllerもしくは@RestControllerのアノテーションを用意する。

### テンプレートエンジン
Javaソースコードの中にHTMLコードを直接記述するのは開発上よろしくない。
JavaのソースコードとHTMLのコードを別々のファイルに分けるため、テンプレートエンジンが利用される。
テンプレートエンジンのHTMLコード内に、Javaの変数を埋め込むことによって利用する。

# おわりに
今回始めてJavaを学習しましたが、他の部分と共通する部分もありつつ、フレームワークの使い方など
まだまだ理解が足りていない部分が多いと感じましたので、
引き続き学習を継続していきたいと思います。