検査例外(Checked Exception)、非検査例外(Unchecked Exception)とは？


# 目次
[結論](#結論)
[例外の3つの種類](#例外の3つの種類)
[検査例外(Checked Exception)](#検査例外checked-exception)
[検査例外(Exception)](#検査例外exception)
[非検査例外(Unchecked Exception)](#非検査例外unchecked-exception)
[発生する検査例外を調べる方法](#発生する検査例外を調べる方法)
[実行時例外(RuntimeException)](#実行時例外runtimeexception)
[エラー(Error)](#エラーerror)
[参考サイト、参考文献](#参考サイト参考文献)




# 結論
- javaでは、[Throwable][1]なクラスの中で、[Errorクラス][2]と、[RuntimeExceptionクラス][3]
を継承したクラスのみ<font  color=red>非検査例外(Unchecked Exception)</font>で、他は全て<font  color=red>検査例外(Checked Exception)</font>
- Exceptionは、スレッドを跨がない
→裏を返すと、沢山のスレッドがある場合は、他のスレッドでExceptionが出ていても分からないので、Exceptionを考慮しないといけなくなる[^1]
[^1]: [Threadクラスのstart()メソッド][4]は、あくまでスレッドを開始させるだけで、開始した後は正常終了したのか、Exceptionが出て異常終了したのか、そもそも開始したスレッドの処理が終わったのかは検知しない

# 例外の3つの種類
- javaでは例外を大きく3つの種類に分けている

↓3つの例外の継承関係
![20240803_213142.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/5e39c781-5de7-2daf-066e-e3fd2916e64b.jpeg)


# 検査例外(Checked Exception)
## 検査例外(Exception)
- 検査例外(Exception)は、<font  color=red>検査例外</font>(チェック例外、Checked Exception)
- 検査例外を表すクラス：[java.lang.Exception][5]
- 主に、プログラム作成時に<INS>想定できる</INS>異常を通知するのに使用する
(その発生を十分に<INS>想定して</INS>、対処を考える筆よ言うがある例外的状況)
-  java.lang.Exceptionクラスを継承した例外の例)
   - [java.io.IOException][6]：ファイルなどが読み書きできない
   - [java.net.ConnectException][7]：ネットワークに接続できない
   - [java.sql.SQLException][8]：データベース・アクセス・エラーまたはその他のエラー
- try-catch文か、throws節が必須(書かないとコンパイルエラーになる)
→プログラムで補足(catch)して処理するか、例外が発生するメソッドの宣言でthrows節を記述する(呼び元のメソッドにthrowする)ことが必須

<details><summary>補足(？)：throws節について</summary>

- throws節をメソッドの宣言に記述することで、メソッド内で例外が発生した場合に自身のメソッド内で補足(catch)するのではなく、呼び出し元の関数に例外を投げる
```java:throws構文
    アクセス修飾子 戻り値 メソッド名(引数) theows 例外クラス1, 例外クラス2{
        // 例外処理を含む処理
    } 
```

```java:例
    public String readFile() throws IOException {
        // ファイルの読み込み処理
    }
```
- throws節をメソッドの宣言に記述することで、その処理で例外が発生することが分かる
- throws節で例外が記述されているメソッドは、呼び出し元の関数側で、その例外に対して何らかの処理をする事がjavaの仕様で決まっている
(例外を処理するコードを記述しないとコンパイルエラーになる)
</details> 

### 発生する検査例外を調べる方法
実装の際に自分が使おうとしている命令で発生するExceptionを調べる方法💭

<INS>__APIリファレンスを見よう！！__</INS>
- APIリファレンスに「どのクラスのどのメソッドが、どのような例外を発生させる可能性があるのか」という情報が掲載されている

例)[FileWriterクラスのコンストラクタ][9]
![2024-08-04_02h06_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/4b9864e2-575c-a754-1164-e29714e43888.png)
↑メソッドやコンストラクタを呼び出した際にExcepoion系の例外がある場合、<font color=red>引数リストの後に「throws例外クラス」が表記されている</font>
この例の場合は、「throws IOException」と記載があるため、「FileWriterクラスのコンストラクタを呼び出す(インスタンスを生成する)ときにはIOExceptionをキャッチするtry-catch文が必要になる」ということが分かる！！

# 非検査例外(Unchecked Exception)
## 実行時例外(RuntimeException)
- 実行時例外(RuntimeException)は、<font  color=red>非検査例外</font>(非チェック例外、Unchecked Exception)
- 実行時例外を表すクラス：[java.lang.RuntimeException][3]
- 主に、プログラム作成時に<INS>想定されない</INS>エラーを通知するために使用する
(必ずしも発生を想定すべきとまでは言えない例外的状況)
↑いちいち想定していると「キリがない」もの
-  java.lang.RuntimeExceptionクラスを継承した例外の例)
   - [java.lang.NullPointerException][10]：変数がnullである
   - [java.lang.ArrayIndexOutOfBoundsException][11]：配列の添え字が不正
- try-catch文も、throws節も書く必要が無い(書かなくてもコンパイルエラーにならない)


<details><summary>もし、try-catch文も、throws節も書かなかった場合</summary>

- catchブロックも、throws節も書かなかった場合、発生した実行時例外は、例外が発生したメソッドの呼び出し元のメソッドに、自動伝搬していく
- 実行時例外をどこでも捕捉しなかった場合、__「例外が発生したメソッドが動いているスレッドが終了してしまう」__
   - 例外が発生したスレッドを開始させた別なスレッド、またはJavaVM自体には例外は伝播しない
   - 例外を発生させたスレッドを開始させたのが

スレッドの場合
![20240804_030819 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/addb2e76-4c22-a0a9-b86b-c8cc21ec0d0d.jpeg)

JavaVMの場合[^2]
[^2]:Java仮想マシン = Javaのプログラムを動かすためのソフトウエア

![20240804_032504-EDIT (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/cf0f57fd-3f1b-0d97-e9d3-8bddca88103a.jpeg)

↑メインスレッドが終わるとアプリケーションが終了するため、もしこのスレッドがJavaVMのメインスレッドであった場合は、アプリケーション自体が終了する

:::note warn
関数のコールと、スレッドは別な話です
(↑自分はごっちゃに考えてしまっていた。。。)
:::
</details> 

## エラー(Error)
 エラー(Error)は、<font  color=red>非検査例外</font>(非チェック例外、Unchecked Exception)
- エラーを表すクラス：[java.lang.Error][2]
- 「通常のアプリケーションでは __捕捉すべきではない__ 重大な問題」を示すクラス
(例外とは異なり、システムの動作を継続できない「致命的なエラー」を示す)
↑回復の見込みが無い、致命的な状況
-  java.lang.Errorクラスを継承した例外の例)
   - [java.lang.OutOfMemoryError][12]：メモリ不足
   - [java.lang.ClassFormatError][13]：クラスファイルが壊れている
- try-catch文も、throws節も書く必要が無い(書かなくてもコンパイルエラーにならない)


<details><summary>「Errorを捕捉すべきではない」理由</summary>

- Errorが発生する状況は大抵の場合、アプリケーションが異常状態に陥っており、速やかにプログラムを終了させるべきだから
→アプリケーションが沈黙する(固まったまま何も動作しなくなる)のは最悪の事態といえるため、速やかに終了すべき
</details> 



# 参考サイト、参考文献
- 谷本心，阪本雄一郎，岡田拓也，秋葉誠，村田賢一郎. Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで. ‎技術評論社, 2017, p.178-181.

- 中山清喬, 国本大悟. スッキリわかるJava入門 第3版 (スッキリわかる入門シリーズ). 株式会社インプレス, 2019, p.658-662.

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Exception.html

https://docs.oracle.com/javase/jp/8/docs/api/java/io/IOException.html

https://docs.oracle.com/javase/jp/8/docs/api/java/net/ConnectException.html

https://docs.oracle.com/javase/jp/8/docs/api/java/sql/SQLException.html

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/RuntimeException.html

https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/io/FileWriter.html#%3Cinit%3E(java.io.File)

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/NullPointerException.html

https://docs.oracle.com/javase/8/docs/api/java/lang/ArrayIndexOutOfBoundsException.html


https://qiita.com/omix222/items/eb3bcdd2fd98794d8a35

https://qiita.com/shunsuke227ono/items/142703c0b046f522f8bd

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/OutOfMemoryError.html

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/ClassFormatError.html

https://docs.oracle.com/javase/jp/7/api/java/lang/Thread.html#start()

https://gakumon.tech/java/java_exception_throw.html


<!-- 以下、埋め込み用URL -->

[1]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Throwable.html
[2]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Error.html
[3]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/RuntimeException.html
[4]:https://docs.oracle.com/javase/jp/7/api/java/lang/Thread.html#start()
[5]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Exception.html
[6]:https://docs.oracle.com/javase/jp/8/docs/api/java/io/IOException.html
[7]:https://docs.oracle.com/javase/jp/8/docs/api/java/net/ConnectException.html
[8]:https://docs.oracle.com/javase/jp/8/docs/api/java/sql/SQLException.html
[9]:https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/io/FileWriter.html#%3Cinit%3E(java.io.File)
[10]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/NullPointerException.html
[11]:https://docs.oracle.com/javase/8/docs/api/java/lang/ArrayIndexOutOfBoundsException.html
[12]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/OutOfMemoryError.html
[13]:https://docs.oracle.com/javase/jp/8/docs/api/java/lang/ClassFormatError.html