現場で聞かれたことをまとめてみた～java編～

# なぜこの記事を書こうと思ったのか
今の現場に参画してから５ヶ月が経ちますが、
現場の方との会話で「どうしてこうなっているんだろう」「この記述は何をしているんだろう」みたいなことが多々あり、
一緒に調べて「なるほど！」となることもありました。

その場で終わらせてしまうのは勿体ないので、
自分への備忘録的に残そうと思いしたためました。
※会話は覚えてる範囲で適当に作ってます。

同じような疑問を持った方がこの記事を見て役立てば幸いです。

# 本題
* プリミティブ型の値をラッパークラスに代入できるのはなぜ？
* tryの後に()がついてるけどこれは何をしているの？
* throwsが必要な例外と、いらない例外があるのはなぜ？

## プリミティブ型の値をラッパークラスに代入できるのはなぜ？
### 疑問
ある日の会話
> Aさん「この`(int)`ってなんですか？」
> 僕「**キャスト**ってやつですね。**型を変えてくれます**。」
> Aさん「へえ、ありがとうございます。」
> ～数日後～
> Aさん「質問なんですけど、**int型の値をキャストしなくてもInteger型の変数に代入できる**んですか？」
> 僕「できますできます。**オートボクシング**だか**アンボクシング**だか、そんな名前の機能だったような…」

```java
public class Sample {

  public void sample(long l) {
    int i = (int) l;
    Integer integer = i;
    log.info("int=[{}], Integer=[{}]", i, integer);
  }
}
```

### 答え
javaには**プリミティブ型(int)からラッパークラス(Integer)へ代入する際、暗黙的に型変換を行ってくれる機能があり、これをオートボクシングと言います**。
オートボクシングとは逆に、**ラッパークラス(Integer)からプリミティブ型(int)へ暗黙的に型変換を行ってくれる機能のことをアンボクシングと言います**。
<font color="Red">アンボクシングには注意が必要</font>で、**ラッパークラスはオブジェクトのためnullを扱えますが、プリミティブ型に代入しようとするとNullPointerExceptionが発生**します。事前に値のチェックを行いましょう。

* プリミティブ型とラッパークラスの一覧

| プリミティブ型 | ラッパークラス |
|:-:|:-:|
|boolean|Boolean|
|byte|Byte|
|char|Character|
|double|Double|
|float|Float|
|int|Integer|
|long|Long|
|short|Short|

## tryの後に()がついてるけどこれは何をしているの？
### 疑問
ある日の会話
> Aさん「**try～catch文**てあると思うんですけど、このtryの後に引数を取ってるのはなんなんですか？」
> 僕「あれなんだっけ…調べてみましょう…」

```java
public void Sample {

  public void sample(Strin url) {
    try (BufferedReader br = new BufferedReader(new FileReader(url))) {
      String line = null;
      while ((line = br.readLine()) != null) {
        System.out.println(line);
      }

    } catch (FileNotFoundException e) {
      e.printStackTrace();

    } catch (IOException e) {
      e.printStackTrace();

    }
  }
}
```

### 答え
javaSE7以降で使用可能な**try-with-resources構文**と呼ばれる記述です。
javaSE6以前はファイルやデータベースへアクセスするとリソースを必ず`close()`する記述をする必要がありましたが、
**try-with-resourcesを使用することでtry句を抜ける際にリソースを自動で`close()`してくれます**。

* 実行順(上から順に実行)
    * try-with-resources部分 (`try()`の部分)
    * try句内
    * try-with-resourcesの`close()`メソッド
    * catch句内
    * finally句内
* その他注意点など
    * try句内で例外が発生し、かつ`close()`でも例外が発生した場合、**try句内で発生した例外がスローされます**。
    * `close()`で発生した例外を使用したい場合は、**`ex.getSuppressed()`でThrowableの配列が取得できます**。
    * `close()`の実行順はリソースを宣言した逆順で実行されます。
    * finally句を記述するとfinally句は実行されます。**ただしtry-with-resourcesで投げられた例外は使用できません**。
    * 自前のリソースを使用したい場合は、`AutoClosableインターフェース`を実装すれば可能になります。 

## throwsが必要な例外と、いらない例外があるのはなぜ？
### 疑問
ある日の会話
> Aさん「このソースについて聞きたいんですけど、**throws**ってなんですか？」
> 僕「**そのメソッドが投げる可能性のある例外を明示的に書いてるだけ**じゃないですか？**なくてもコンパイルは通るんじゃ…？**」
> Aさん「**throws AAAExceptionを消すと怒られる**んですよね…なんででしょう？」
> 僕「……なんででしょうね？**BBBExceptionは書かなくても大丈夫**なのに…」

```java:
public class Sample {

  public Object sample(String url, Request request) throws AAAException {

    XXXClient client = new XXXClient();

    try {
      return client.request(url, reuqest);

    } catch (AAAException ex) {
      log.error("何かしらのログ", ex);
      throw ex;

    } catch (BBBException ex) {
      log.error("何かしらのログ", ex);
      throw ex;

    }
  }
}
```
### 答え
Javaには**検査例外(チェック例外)**と**非検査例外(非チェック例外)**と呼ばれる２種類の例外が存在します。(厳密には**error**もありますがここでは割愛)
**検査例外が発生しうるメソッドに対してthrowsが必要**になります。
今回の例でいうと、**AAAExceptionが検査例外だったためthrowsが必要となり、BBBExceptionは非検査例外だったためにthrowsを付ける必要がなかった**わけです。

* 検査例外
    * 正しい記述をして想定通りの挙動をしてもthrowされる例外 (≒実装プログラムではどうしようもない)
    * 予め予想できるエラーなので、呼び出し元にハンドリングを強制させる必要がある(throws必須)
    * java.lang.Exceptionのサブクラス
        * IOException…入出力エラー
        * FileNotFoundException…ファイルが見つからない
        * SQLException…SQLエラー　　　　　　　　　　　　……etc
    * <font color="Red">javaしか持たない概念らしい</font>

* 非検査例外
    * 様々な原因でthrowされる例外 (≒実装プログラムで回避できる)
    * 発生しうる全パターンを予想しきるのは困難であるため、呼び出し元にハンドリングは強制させず実行中止する
    * java.lang.RuntimeExceptionのサブクラス
        * NullPointerException…値がNULL
        * NumberFormatException…値が数値に変換できない
        * ArrayIndexOutOfRangeException…リストや配列の範囲外である　　……etc
    * <font color="Red">他言語は基本的に非検査例外しか存在しない</font>

* 簡単なクラス図
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/188440/8b776fe2-8cd4-7fba-cf2f-e238489052fb.png)

# 最後に
誰かにアウトプットすることは自分自身が本当に理解できているのかを確認する機会になります。
改めて調べなおすとさらに理解が深まりとても勉強になりました。
今後も随時更新していきます！

最後までお読みいただきありがとうございました！