try-catch文の使い方まとめ①

## 目次
　[1.try-catch文とは](#1-try-catch文とは)
　[2.try-catch文の使い方](#2-try-catch文の使い方)
　[3.try-catch-finally文の使い方](#3-try-catch-finally文の使い方)
　[4.try-catch文使用の注意](#4-try-catch文使用の注意)

※「try-catch文の使い方まとめ②」はこちら↓


https://qiita.com/osakanaaaa/items/551acec833af96e4bf4a


## 1. try-catch文とは
処理の中で発生したエラーを例外（Exception）といい、例外が発生すると異常終了してしまう。
しかし、try-catch文で例外をキャッチすることで、例外発生箇所をスキップしたり、
例外の内容ごとに処理をおこなったりすることができ、異常終了を防ぐことができる。

## 2. try-catch文の使い方
### 基本構文
```java
try {
    // 例外が発生する可能性のある処理
} catch (Exception e) {
    // 例外発生時の処理
}
```
catch句に例外クラスを指定することで、例外の内容ごとに処理をおこなうことができる。

### 実装例1（例外発生ver.）
```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
		
		String str1 = "おさかな";
		
		try {
		    Double.parseDouble(str1);
		    System.out.println(str1 + "：この文字列は数字です");
		    
		} catch (NumberFormatException e) {
		    System.out.println(str1 + "：この文字列は数字ではありません");
		}
	}
}
```
tryブロッックで"おさかな"という文字列が数字かどうかをチェック。
DoubleクラスのparseDoubleメソッドを使用し、文字列を数値のDouble型に変換。
数字でない文字列やnullは変換不可のため、今回は例外がスローされる。
そのためcatchブロックに入り「この文字列は数字ではありません」が出力される。

### 実装例2（例外発生ver.）
```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
		
		String str1 = "おさかな";
		String str2 = "12345";
		
		try {
			Double.parseDouble(str1);
		    System.out.println(str1 + "：この文字列は数字です");
			
			Double.parseDouble(str2);
		    System.out.println(str2 + "：この文字列は数字です");
		    
		} catch (NumberFormatException e) {
		    System.out.println("この文字列は数字ではありません");
		}
	}
}
```
まずはじめに、str1の"おさかな"が数字かどうかのチェックをおこなう。
数字でないためそれ以降の処理はおこなわず、catchブロックに入る。
そのため出力結果は「この文字列は数字ではありません」。

（例外発生しないver.の例はこれより下の実装例3にあります）

## 3. try-catch-finally文の使い方
### 基本構文
```java
try {
    // 例外が発生する可能性のある処理
} catch (Exception e) {
    // 例外発生時の処理
} finally {
    // 例外発生有無に関わらず必ず最後におこなう処理
}
```
tryブロック内で例外が発生した場合、tryブロック内のそれ以降の処理はおこなわれない。そのため、
例外発生有無に関わらず最後におこないたい処理がある場合は、finallyブロックに処理を記載する。
※tryブロック内にreturnを記載しても、finallyブロック内の処理はおこなわれる。
※tryブロック内で例外が発生しない場合は、tryブロック内のすべての処理が実行される。


### 実装例3（例外発生しないver.）
```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
		
		String str2 = "12345";
		
		try {
			Double.parseDouble(str2);
		    System.out.println(str2 + "：この文字列は数字です");
		    return;
		    
		} catch (NumberFormatException e) {
		    System.out.println(str2 + "：この文字列は数字ではありません");
		    
		} finally {
			System.out.println("チェックが完了しました");
		}
	}
}
```
str2の"12345"は数字のため、例外はスローされず、tryブロック内の全ての処理が実行される。
tryブロック内にreturnを記載しても、finallyブロック内の処理はおこなわれるため、
出力結果は「12345：この文字列は数字です」と「チェックが完了しました」。

## 4. try-catch文使用の注意
### 例外をキャッチして何も処理をおこなわないのはNG
```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
		
		String str1 = "おさかな";
		
		try {
		    Double.parseDouble(str1);
		    System.out.println(str1 + "：この文字列は数字です");
		    
		} catch (NumberFormatException e) {
		}
	}
}
```
上記のように例外をキャッチして何も処理をおこなわない場合、
例外が発生しているのかどうかもわからなくなってしまう。
そのため、catchブロック内の記載漏れには十分注意が必要。

### tryブロックは適切な範囲で囲む
適切でない囲み方の例
```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
				
		String str2 = "12345";
		String str3 = null;
		
		try {
		    Double.parseDouble(str2);
		    System.out.println(str2 + "：この文字列は数字です");
		    
		    System.out.println(str3.length());
		    
		} catch (NumberFormatException e) {
		    System.out.println("この文字列は数字ではありません");
		    
		} catch (NullPointerException e) {
		    System.out.println("これはnullです"); 
		}
	}
}
```
まずstr2は数字のため「12345：この文字列は数字です」が出力される。
str3はnullなのでlength()でNullPointerExceptionになり、
ふたつ目のcatchブロックに入り、「これはnullです」が出力される。
この実装だと、どの処理で例外を投げているのか分かりにくい（可読性が低い）ため、
tryブロックは下記のように適切な範囲で囲む。

適切な囲み方の例
```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {

		String str2 = "12345";
		String str3 = null;

		try {
			Double.parseDouble(str2);
			System.out.println(str2 + "：この文字列は数字です");

		} catch (NumberFormatException e) {
			System.out.println("この文字列は数字ではありません");
		} 

		try {
			System.out.println(str3.length());

		} catch (NullPointerException e) {
			System.out.println("これはnullです");
		}
	}
}
```
出力結果「12345：この文字列は数字です」「これはnullです」

## 関連記事

https://qiita.com/osakanaaaa/items/dc98efab6b490905e57d