プログラミングド素人のデザイナーがJava入門してみた_その7

## 前回までのあらすじ
[プログラミングド素人のデザイナーがJava入門してみた_その6](http://qiita.com/iwashi0830/items/dd6c2f1c46c8696bf4be)

## 列挙型
- クラスのように自分で作れるデータ型
- **定数**をまとめたもの
- とり得る値が明確に決まっている時などに使う?
    - 信号の色とか?
- 最後の値の後にも`,`をつけておくと、値を付け足すとき便利

```java
//列挙型を宣言
enum Hoge{
  値a,
  値b,
  値c,
}
```

- 変数の宣言時はnewしなくてもいいっぽい
- 値を呼びだすときは`Hoge.値`と書く

```java
//列挙型の変数として宣言
Hoge hoge = Hoge.値a;
```

### 連番を取得
- 列挙型を宣言すると、登録した定数の連番を取得できるメソッドがついてくる
- `インスタンス名.ordinal()`で取得可能

```java
//列挙型を宣言
enum Hoge{
  値a,//0番目
  値b,//★1番目
  値c,//2番目
}

//中略

Hoge hoge = Hoge.値b;
//連番を取得
System.out.println(hoge.ordinal())//★1
```

### 信号機の挙動を書いてみる

```java
enum Signal{//★列挙型の宣言
  RED,//0番目
  YELLOW,//1番目
  BLUE,//2番目
}

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

    Signal signal = Signal.RED;//列挙型のSignalに登録されたREDを格納

    switch(signal){
      case RED:
        System.out.println("止まれ");//これが呼ばれる
        System.out.println(signal.ordinal());//REDの連番0が呼ばれる
        break;
      case YELLOW:
        System.out.println("注意");
        break;
      case BLUE:
        System.out.println("進め");
        break;
    }
  }
}
```

## 例外処理
### エラーとは
- エラーには**コンパイルの時点で発生**するものとプログラムの**実行中に発生**するものがある
- コンパイルの時点のエラーは文法的ミス
- 実行中に発生するエラーは、ユーザー入力や、動的要素に関するプログラムに依るもの
- これを**例外**または予期せぬエラーという
    - (コンパイル時には検出できなかったエラーということ?)

### 例外処理とは、予期せぬエラーが発生した時の処理を書くこと
- 本来はエラー扱いとなりプログラムが終了してしまう結果も、予め起こりうるものとしておくことで、終了させずに任意の処理を実行できる
    - 0除算など通常はエラーとなって終了してしまう記述でも、例外処理によってプログラムを続行できる
- Javaには予めいくつかの例外に対してクラス(Exceptionクラス)が用意されている。
    - ArithmeticExceptionクラスは算術計算での例外

### 例外処理の書き方

```java
try{
  例外が発生する可能性のある処理
} catch(例外クラス名 変数名){ //↑で発生した例外が、chatchで示したものであった場合実行
  例外が発生した時の処理 
}
```

```java
public class HelloWorld {

  public static void div(int a, int b) {
    try{
        System.out.println(a/b);//この処理でbに０が代入されたら算術計算の例外(エラー)が起きる
    } catch (ArithmeticException e){//算術計算のエラーが起きたら下記を実行
        System.err.println(e.getMessage());// / by zero(ArithmeticExceptionクラスが持っているメッセージ?)
    }

  }

  public static void main(String[] args) {
    div(3, 0);//0除算は算術計算エラーなので例外が発生する
  }

}
```

### 自分で例外を設定する
- 上記の例外処理は、Javaに予め用意されている例外しか検知できない
- 独自に例外を定義することもできる

```java
//独自の例外クラスを定義
class クラス名 extends Exception { //標準のExceptionクラスを継承
  public MyException(String s){ //コンストラクタの引数で、例外発生時のメッセージ内容をStringで受ける
    super(s); //親クラスのExceptionのコンストラクタに引数で受けたメッセージ内容を渡す
  }
}

public class HelloWorld {

  public static void div(hoge a, hoge b) {
    try{
      if(例外としたい条件){//独自に決めた例外が発生したら下記を実行
        throw new 独自の例外クラス名("エラーメッセージ");//throwで独自に作った例外クラスのインスタンスを発生させる(投げる)?
      }
      処理
    } catch (独自の例外クラス名 e){ //独自の例外が発生したら下記を実行
        System.err.println(e.getMessage());//エラーメッセージ
    }

  }
```

```java
class MyException extends Exception {//独自の例外クラスMyExceptionクラスを定義
  public MyException(String s){//コンストラクタ
    super(s);
  }
}

public class HelloWorld {

  public static void div(int a, int b) {
    try{
      if(b < 0){//bがマイナスの値だった場合例外として処理する
        throw new MyException("not minus!");//定義した独自例外クラスMyExceptionクラスのインスタンスを生成して例外を発生させる
      }
      System.out.println(a/b);
    } catch (ArithmeticException e){//chatchは複数書ける
        System.err.println(e.getMessage());
    } catch (MyException e){//MyExceptionの例外を検知したら下記を実行
        System.err.println(e.getMessage());//MyExceptionのエラーメッセージを表示
    }

  }

  public static void main(String[] args) {
    div(3, 0);
    div(3, -1);//bがマイナスなのでMyExceptionの例外が発生
  }

}
```

### 例外があろうがなかろうが実行したい処理
- `finally`のブロックの処理は例外の有無にかかわらず実行

```java
public class HelloWorld {

  public static void div(int a, int b) {
    try{
      System.out.println(a/b);
    } catch (ArithmeticException e){
      System.err.println(e.getMessage());
    } finally { //例外の有無に関係なく実行
      System.out.println("---end---");
    }
  }

  public static void main(String[] args) {
    div(3, 0);
    div(3, -1);
  }

}
```

## ラッパークラス
- 基本データ型には、それぞれに対応する参照型クラスが用意されており、これらをラッパークラスという
 - intにはInteger,doubleにはDoubleといった具合
- Javaのクラスによっては参照型しか受け付けないものがあるので、相互に変換できるようにしておく必要がある

### 基本データ型→参照型　の変換
- intに対応する参照型クラスのIntegerのインスタンスを格納

```java
Integer i = new Integer(32);
```

もしくは

- 普通の変数宣言の形でも使える
- あくまで↑の処理に自動変換されており、このことを**auto boxing**という

```java
Integer i = 32;//auto boxing
```

### 参照型→基本データ型　の変換

```java
Integer i = new Integer(32);
int n = i.intValue();
```

もしくは

- 普通の代入の形でも使える
- あくまで↑の処理に自動変換されており、このことを**auto unboxing**という

```java
Integer i = 32;
int n = i//auto unboxing
```



## 教科書
[ドットインストール](http://dotinstall.com/)さまさま

- [#30 列挙型を作ってみよう](http://dotinstall.com/lessons/basic_java_v2/37730)
- [#31 例外処理を扱ってみよう](http://dotinstall.com/lessons/basic_java_v2/37731)
- [#32 ラッパークラスを使ってみよう](http://dotinstall.com/lessons/basic_java_v2/37732)



## [@iwashi0830](https://twitter.com/iwashi0830)はこう思った
- ドットインストールの例外処理の動画は説明端折り過ぎ(自分で色々調べてようやく納得できた)
- 独自の例外クラス作る意味って...?
    - if文のブロックに処理書けばいいだけじゃないの...?
- finallyの意味って...?
    - 例外の有無にかかわらず実行するならtryとか関係なくない?
- ラッパークラスが普通の変数宣言と同じように書けるのいいね