Java予約語まとめ

# Javaの予約語まとめ

## 目次

* 予約語とは
* 予約語の一覧
* 各予約語の説明

## 予約語とは

* プログラミング言語において、あらかじめ用途が決められた単語のこと。基本的に、識別子（クラス名、関数名、変数名）は自由に設定する事ができるが、予約語と同じ名前は使えない。

## 予約語の一覧

||||||
|---|---|---|---|---|
|abstract|assert|boolean|break|byte|
|case|catch|char|class|const|
|continue|default|do|double|else|
|enum|extends|final|finally|float|
|for|goto|if|implements|import|
|instanceof|int|interface|long|native|
|new|package|private|protected|public|
|return|short|static|strictfp|super|
|switch|synchrnized|this|throw|throws|
|transient|try|void|volatile|while|
|_|

## 各予約語の説明

### abstract

* 抽象クラスの宣言を行う際に用いられる。
* 抽象クラスとは、以下のような中身のないメソッドを持っているクラスのこと。  
```
abstract メソッド名(引数, 引数, ...);
```

#### どのような時に使うのか

* 複数人で開発を行う場合に、実装レベルのルールを作成したいとき。
* メソッド名を統一し、ロジックを共通化し、大体何の処理を行っているか把握したいとき。
* 共通の処理を全てのクラスの毎回書き込みたくないとき。
* 開発者がサブクラスを定義した時に、メソッドの実装忘れや、メソッド名に間違いがないか確認できるようにしたい時。

#### サンプルコード

```
abstract class AbstractClass {
  abstract public void method();
}

class ConcreteClass extends AbstractClass{
  public void method(){
    // 実装内容
  }
}

AbstractClass c = new AbstractClass(); // コンパイルエラー
AbstractClass c = new ConcreteClass(); // 可
ConcreteClass c = new ConcreteClass(); // 可
```

### assert

* abstract:抽象クラスの宣言の際に使用する
* assert：プログラムの動作検証（アサーション）に使用される。
* アサーション（動作検証）とは：プログラムが正常に動作しているかどうか確認するための手法。プログラムの各所にその時点で必ず真（true）となる条件を宣言しておくと、実行時にその条件が満たされない状態になるとJavaが自動で検知し、AssertionErrorが返される。
* 実行の際に -enebleassertions（または -ea）というオプションを渡すことでアサーションの有効無効を切り替えられる。

#### どのような時に使うのか

* デバッグ支援を行いたいとき。
* ソースコードにおける開発者の意図をプログラムに記述したいとき。

#### サンプルコード

```
private int divide(int x, int y) {
    assert y != 0 : y + “は0より大きい数字でないといけない”;

    return x / y;
}
```

### boolean

* trueまたはfalseのどちらかのデータが必ず入ることを表す、データ型。
* インスタンス変数として宣言した場合は、初期値でfalseが入るが、ローカル変数で宣言した場合は、初期値が設定されないので、設定しないといけない。
  * インスタンス変数：クラス内で宣言した変数
  * ローカル変数：メソッド内で宣言した変数
* Booleanというものもあり、こちらはクラスとして使用される。また、booleanはnullが表現できないのに対して、Booleanはnullも扱える。ただし、変数がnullであることを設定しないとNullPointerExceptionとなる。

#### どのような時に使うのか

* 数値や文字列の比較結果を表す時。
* if文で分岐の方向を表す時。
* for文やwhile文でループを続行するか決定する時。

#### サンプルコード

```
//if文での場合
public class Main {
    public static void main(String[] args) throws Exception {
        boolean bool1 = false;
        
        if(bool1) {
          System.out.println("bool1の値はtrueです");            
        } else {
          System.out.println("bool1の値はfalseです");
        }
        
        int number = 100;
        
        boolean isResult = number < 200;
        
        if(isResult) {
          System.out.println("isResultの値はtrueです");            
        } else {
          System.out.println("isResultの値はfalseです");    
        }
 
    }
}
//実行結果
bool1の値はfalseです
isResultの値はtrueです

//while文の場合
public class Main {
    public static void main(String[] args) throws Exception {
        boolean bool = true;　// 初期値設定
        int count = 1; // 初期値設定
        
        while(bool) {
            System.out.println("countの値は" + count + "です。");  
            if(count == 5) {
                bool = false; // countの値が5になれば実行される処理
            }
            count++; // 変数「count」の値に1を足す。
        }
 
    }
}
//実行結果
countの値は1です。
countの値は2です。
countの値は3です。
countの値は4です。
countの値は5です。

//Boolean型の場合
public class Main {
    public static void main(String[] args) throws Exception {
        Boolean bool = null;
        
        if(bool == null) {
            System.out.println("boolの値はnullです");
        } else if(bool) {
            System.out.println("boolの値はtrueです");
        } else {
            System.out.println("boolの値はfalseです");            
        }
 
    }
}
//実行結果
boolの値はnullです
```
### break

* break文はfor文、while文、do..while文、switch文のブロック内で使用され、処理の途中で抜け出すために使用される構文。最も内側の１つのループ（繰り返し処理）から抜け出す。二重ループを抜け出す際は、最初のfor文にラベル（名前のようなもの）を付け、breakで抜ける際にそのラベルを指定すると、抜けられる。

#### どのような時に使うのか

* 特定の条件で、その処理を終え、次の処理を実行させたい時。

#### サンプルコード

```
//switch文の場合
public static void main(String[] args) {
  int num = 3;
  switch(num) {
    case 1:
      System.out.println("1ですよ");
      break;
    case 2:
      System.out.println("2ですよ");
      break;
    case 3:
      System.out.println("3ですよ");
      break;
    case 4:
      System.out.println("4ですよ");
      break;
    default:
      System.out.println("defaultですよ");
  }
}
//実行結果
3ですよ

//for文の場合
public static void main(String[] args) {
  for (int i = 1; i <= 5; i++) {
    if (i == 3) {
      break;
    }
    System.out.println(i + "回目");
  }
  System.out.println("終了です");
}
//実行結果
1回目
2回目
終了です

//while文の場合
public static void main(String[] args) {
  int num = 1;
  while(true) {
    if (num == 3) {
      break;
    }
    System.out.println(num + "回目です");
    num++;
  }
  System.out.println("終了です");
}
//実行結果
1回目です
2回目です
終了です

//二重ループの場合
loop1: for(初期化式; 条件式; 変化式){//for文の名前をloop1に指定
        for(初期化式; 条件式; 変化式){
                if(forループを抜ける場合の条件式) break loop1;//抜けるfor文をloop1に指定

                処理内容
        }
}
//実行結果
条件に当てはまった時、loop1の処理を抜け出す
```

### byte

* 整数のデータ型で、プリミティブ（primitive、基本データ型）と呼ばれるものの1つ。
* -128〜127の整数を表現できる。

#### どのような時に使うのか

* バイナリファイルや、バイナリデータを「そのまま」扱う時。
  * バイナリファイル：バイナリデータのファイル。このうちテキストエディタで扱えるものはテキストファイルに分類される。
  * バイナリデータ：コンピューターが直接処理するために２進数で表現されるデータのこと。
  * 動画視聴の際のストリーミングの際にサーバから送られてくるデータはバイナリデータである。
* 1つの変数としてではなく、配列にしてバイナリデータの集まりを表すのによく用いられる。

#### サンプルコード

```
// byte型の変数の宣言と、初期値の代入
byte b = 100;
 
// byte型の配列の宣言と、各インデックスへの値の代入
byte[] byteArray1 = new byte[3];
byteArray1[0] = 11;
byteArray1[1] = 12;
byteArray1[2] = 13;
 
// byte型の配列の宣言と、初期化を同時に行う
byte[] byteArray2 = { -128, 0, 127 };
```
### switch

* 条件分岐処理を行う予約語。

#### どのような時に使うのか

* 条件分岐先が複数ある際に用いる。

#### サンプルコード

```
public class Main {
  public static void main(String[] args) {
    int num = 3;
    switch(num) {
    case 1:
      System.out.println("変数numは1です");
      break;
    case 2:
      System.out.println("変数numは2です");
      break;
    case 3:
      System.out.println("変数numは3です");
      break;
    case 4:
      System.out.println("変数numは4です");
      break;
    default:
      System.out.println("変数numは1から4の整数ではありません");
    }
  }
}
//実行結果
変数numは3です
```

### case

* switch文の条件分岐処理を行う際に使う予約語。

#### どのような時に使うのか

* switch文の条件分岐先を記述する際に使用する。

#### サンプルコード

```
public class Main {
  public static void main(String[] args) {
    int num = 3;
    switch(num) {
    case 1:
      System.out.println("変数numは1です");
      break;
    case 2:
      System.out.println("変数numは2です");
      break;
    case 3:
      System.out.println("変数numは3です");
      break;
    case 4:
      System.out.println("変数numは4です");
      break;
    default:
      System.out.println("変数numは1から4の整数ではありません");
    }
  }
}
//実行結果
変数numは3です
```
### default

* switch文で条件に当てはまらなかった際の処理を行うための予約語。
* interfaceに実装するメソッドを持たせるための予約語。

#### どのような時に使うのか

* switch文で条件に当てはまらない場合の処理を時実行する際に用いる。
* インターフェースにメソッドを持たせたいとき。

#### サンプルコード

```
public class Main {
  public static void main(String[] args) {
    int num = 5;
    switch(num) {
    case 1:
      System.out.println("変数numは1です");
      break;
    case 2:
      System.out.println("変数numは2です");
      break;
    case 3:
      System.out.println("変数numは3です");
      break;
    case 4:
      System.out.println("変数numは4です");
      break;
    default:
      System.out.println("変数numは1から4の整数ではありません");
    }
  }
}
//実行結果
変数numは1から4の整数ではありません

//interfeceの場合
interface Foo{
    void print(String s);
    default void twice(String s){
        print(s);
        print(s);
    }
}
```

### try

* 例外が発生する可能性のある処理に使う予約語。

#### どのような時に使うのか

* 例外が発生した際の処理を行いたい場合に、例外が発生する可能性がある処理を記述するために用いる。
* 処理の中で、不具合が起きた際の原因を把握したい場合。

#### サンプルコード

```
public class Main {
 
    public static void main(String[] args) {
        int result;
        result = div(5, 0);
        System.out.println("戻り値 = " + result);
    }
 
    public static int div(int num1, int num2) {
        try {
            int result = num1 / num2;
            
            return result;
 
        } catch (ArithmeticException e) {
            System.out.println("例外が発生しました。");
            System.out.println(e);
 
            return 0;
        }
    }
 
}
```
### catch

* 例外が発生した時の処理を行うための予約語。
* 以下のように記述する。  
```
catch(例外クラス 変数名) {
  例外処理;
}
```
* 例外クラス：以下のようなものがある。
  * Throwable
    * Error
      * Error系例外
        * OutOfMemoryError
        * ClassFormatError ...etc.
    * Excption
      * Exception系例外
        * IOException
        * ConnectException ...etc.
      * RuntimeException系例外
        * NullPointException
        * ArrayIndexOUtOFBOUndsExeception ...etc.

#### どのような時に使うのか

* 例外が発生する可能性ある処理がある際に、実際に例外が起きた際に行いたい処理を記述する際に用いる。

#### サンプルコード

```
public class Main {
 
    public static void main(String[] args) {
        int result;
        result = div(5, 0);
        System.out.println("戻り値 = " + result);
    }
 
    public static int div(int num1, int num2) {
        try {
            int result = num1 / num2;
            
            return result;
 
        } catch (ArithmeticException e) {
            System.out.println("例外が発生しました。");
            System.out.println(e);
 
            return 0;
        }
    }
 
}
//実行結果
例外が発生しました。
java.lang.ArithmeticException: / by zero
戻り値 = 0
```

### finally

* 例外の発生有無にかかわらず、実行する処理を宣言する予約語。

#### どのような時に使うのか

* 例外が発生しそうな処理がある際に、例外の発生の有無にかかわらず、実行したい処理を記述する際に使用する。

#### サンプルコード

```
int n[] = {18, 29, 36};

System.out.println("開始します");

try{
  for (int i = 0; i < 4; i++){
    System.out.println(n[i]);
  }
}
catch(ArrayIndexOutOfBoundsException e){
  System.out.println("配列の範囲を超えています");
}
finally{
  System.out.println("配列の出力を終了しました");
}

System.out.println("終了しました");
```
### throw

* 例外を意図的に起こし、例外処理するための予約語。
  * 意図的に例外を起こすとは：ある条件と一致する場合に例外を発生させ、エラーメッセージを返すということ。

#### どのような時に使うのか

* 処理を行う際に例外を発生させたい時に使用する。

#### サンプルコード

```
public class Main {
 
    public static void main(String[] args) {
        int result;
        result = div(5, 0);
        System.out.println("戻り値 = " + result);
    }
 
    public static int div(int num1, int num2) {
        try {
            if (num2 == 0) {
                throw new ArithmeticException("0で割ったときの例外を発生させる");
            }
            int result = num1 / num2;
 
            return result;
 
        } catch (Exception e) {
            System.out.println("例外が発生しました。");
            System.out.println(e);
 
            return 0;
        }
    }
 
}
//実行結果
例外が発生しました。
java.lang.ArithmeticException: 0で割ったときの例外を発生させる
戻り値 = 0
```

### throws

* 例外が発生した場合に、呼び出し元に例外処理を行わせることができる予約語。
* 呼び出し元とは：以下のコードにおいて、mainはmathメソッドを呼び出しているので、mainが呼び出し元、mathが呼び出し先となる。
```
public static void main(String[] args) {
    int num = 10;

    math(num);

    math(int i) {
        int i += 100;
    }
}
```

#### どのような時に使うのか

* 呼び出し元のメソッドで呼び出し先のメソッドの例外発生の処理を行いたい時に使用する。
* mainメソッドで様々なメソッドを呼び出して、そこで例外処理を行うことで可読性をあげることができる。

#### サンプルコード

```
public class Main {
 
    public static void main(String[] args) {
        int result = 0;
        try {
            result = div(5, 0);
        } catch (Exception e) {
            System.out.println("例外が発生しました。");
            System.out.println(e);
        }
 
        System.out.println("戻り値 = " + result);
    }
 
    public static int div(int num1, int num2) throws ArithmeticException {
        int result = num1 / num2;
 
        return result;
    }
 
}
//実行結果
例外が発生しました。
java.lang.ArithmeticException: / by zero
戻り値 = 0
```

### for

* 繰り返し処理を作成できる予約語。
```
for(初期化式; 条件式; 変化式){
　実行する処理
}
```
* 拡張for文というものもあり、以下のように記述する。
```
for (型 変数名: 配列名もしくはコレクション名){
　実行する処理
}
```
#### どのような時に使うのか

* 繰り返し処理を行う際に用いる。

#### サンプルコード

```
public class sample {
    public static void main (String[] args){
        int sum = 0;//[1]
        for (int number = 1; number <= 10; number++) {//[2]
            sum += number;//[3]
        }
        System.out.println("sum:" + sum);//[4]
    }
}
//実行結果
sum:55
```

### continue

* for文やwhile文などの繰り返し処理の途中で残りの処理をスキップして繰り返しの先頭に戻るための予約語。

#### どのような時に使うのか

* 繰り返し処理を行う際に一定の条件の際に残りの処理をスキップして繰り返し処理の先頭に戻る処理を行いたい場合に用いる。
* 繰り返し処理の中でしか、使えない。

#### サンプルコード

```
class sample{
    public static void main(String args[]){
  
      for (int i = 1; i < 10; i++){
        if (i % 2 == 0){//この場合は、iの値が偶数の時だけ(1)の処理をスキップすることになる
          continue;
        }
  
        System.out.println("i = " + i);//(1)
      }
    }
  }
//実行結果
i = 1
i = 3
i = 5
i = 7
i = 9
```

### if

* 条件分岐を行うための予約語。

#### どのような時に使うのか

* 以下の6つの使い方がある。
  * 1.if-else文で複数条件がある場合の記述方法
  * 2.比較演算子(等号・不等号)の使い方
  * 3.論理演算子(OR・AND・NOT)の使い方
  * 4.三項演算子でif-else文を1行に省略した記述方法
  * 5.文字列の一致(イコール)/文字列を含むものを確認する方法
  * 6.breakやcontinueでループを制御する方法

#### サンプルコード

```
//1の場合
public class Main{
  public static void main(String[] args){
    int number = 80;
 
    if (number > 90) {
      System.out.println("素晴らしい結果です！");
    } else if (number > 60) {
      System.out.println("まぁまぁの結果です。");
    } else {
      System.out.println("もう少し頑張りましょう。");
    }
  }
}
//実行結果
まぁまぁの結果です。

//2の場合
public class Main{
  public static void main(String[] args){
    int number = 10;
    if (number < 20) {
      System.out.println(number + "は20より小さい値です");
    }
  }
}
//実行結果
10は20より小さい値です

//3の場合
public class Main{
  public static void main(String[] args){
    int number = 10;
 
    if ((number < 20) || (number >= 10)) {
      System.out.println(number + "は10以上または20未満の値です");
    }
  }
}
//実行結果
10は10以上または20未満の値です

//4の場合
public class Main {
    public static void main(String[] args) {
 
        int number = 10;
        String str = (number == 5) ? "numberは5です" : "numberは5ではありません";
        System.out.println(str);
    }
}
//実行結果
numberは5ではありません

//5の場合
public class Main {
    public static void main(String[] args) {
 
        String str1 = "ポテパン";
        if(str1 == "ポテパン") {
          System.out.println("str1 は文字列「ポテパン」と一致します");
        } else {
          System.out.println("str1 は文字列「ポテパン」と一致しません");
        }
    }
}
//実効結果
str1 は文字列「ポテパン」と一致します
```
### else

* if文で条件分岐を行う際に、条件はfalseだった場合の処理を行うための予約語。

#### どのような時に使うのか

* if文において、条件を満たさない場合、の処理を記述する際に用いる。


#### サンプルコード
 ```
class sample {
    public static void main (String[] args){
        int number = 200;//[1]
        if (number >= 1 && number <= 9){//[2]
            System.out.println("[3] number : 1 - 9");
        } else if (number >= 10 && number <= 99) {//[4]
            System.out.println("[5] number : 10 - 99");
        } else {//[6]
            System.out.println("[7] number >= 100");
        }
    }
}
//実行結果
[7] number >= 100
 ```
### char

* 1文字を格納できる型。
* 16ビットUnicodeで表現したものを用いる。
* 16ビットUnicodeとは：文字に0~65535の番号を当てたもの。

#### どのような時に使うのか

* 1文字を格納する際に用いる。

#### サンプルコード
```
class sample {
    public static void main(String[] args) {
        char  chrHensu1 = 'A';      // Aをそのまま代入
        char  chrHensu2 = 0x0041;   // 0x0041を指定
        char  chrHensu3 = 65;       // 65を指定
         
        System.out.println(chrHensu1);
        System.out.println(chrHensu2);
        System.out.println(chrHensu3);
    }
}
//実行結果
A
A
A
```
### class

* クラスを宣言する予約語。

#### どのような時に使うのか

* クラスを宣言する際に用いる。

#### サンプルコード

```
class クラス名 {
   実行処理...
}
```

### const

* 無効な予約語。
* C言語/c++言語では「定数」を意味する予約語。
* Javaでは、「final」に相当する。

#### どのような時に使うのか

* 予約語であるので、変数名や、関数名、クラス名には使用できない。

#### サンプルコード

* なし

### do

* while文と共に用いられる予約語。

#### どのような時に使うのか

* 繰り返し処理では普通、最初の条件式の評価を実行してから繰り返し処理を開始する。場合によっては一度も処理をされずに次の処理を実行する可能性もある。
* このような状況にならないように、まず一度だけwhile文の処理を行いたい場合に用いる。

#### サンプルコード

```
public class sample {
    public static void main(String[] args) {
        int i = 0;
        do {
            System.out.println((i + 1) + "回目の処理です");
            i++;
        } while (i < 3);
        System.out.println("処理が終了しました");
    }
}
//実行結果
1回目の処理です
2回目の処理です
3回目の処理です
処理が終了しました
```
### double

* 少数を扱えるデータ型の1つ。
* クラスのDoubleもあり、これはnullも表現できる。
  * 代入した数字にミスがあり、値がない時にnullとして表現できる。

#### どのような時に使うのか

* 10^303~10^-324乗の範囲の大きな数字を扱う場合に用いる。
* doubleの変数に代入できる数字の書き方は以下のとおり。
  * 10進数(整数、小数)
  * 10進数+指数表記
  * 2進数(0b始まり、整数)、Java 7以降
  * 8進数(0始まり、整数)
  * 16進数(0x始まり、整数)
  * 16進数+指数表記

#### サンプルコード

```
// 10進数の小数点ありの数字と、2進数・8進数・16進数の整数
double d1 = 12345; // 10進数(整数)
double d2 = 1.2345; // 10進数(小数点以下あり)
double d3 = -123_456.789_012; // 10進数、区切り文字あり
double d4 = 0b0101; // 2進数の整数
double d5 = 012345; // 8進数の整数
double d6 = 0x12345; // 16進数の整数

// 10進数と16進数の指数表記
double d1 = 1.23e4; // 10進数 指数表記(1.23×10の4乗) → 12300
double d2 = -1.23e-4; // 10進数 指数表記(-1.23×10の-4乗) → -0.000123
double d3 = 0x1.23p4; // 16進数 指数表記(0x1.23×2の4乗) → 18.1875
double d4 = -0x1.23p-4; // 16進数 指数表記(-0x1.23×2の-4乗) → -0.071044921875

// 接尾語としてd/Dを付ければ、そのリテラルはdouble扱いになる
double d1 = 5 / 10; // → 0、intの5をintの10で割るので、計算結果はintの0になる
double d2 = 5 / 10d; // → 0.5、intの5をdoubleの10で割るので、5もdoubleになり、計算結果はdoubleの0.5になる

```
### enum

* 複数の定数を1つにまとめておくことができる型のこと。
* クラスであるので、フィールドやメソッドを定義することができる。
  * 注意点
    * Enumクラスの列挙子には値を付与することができますが、その場合はフィールドとコンストラクタを定義する必要がある。
    * Enumクラスのコンストラクタのアクセス修飾子はprivateのみ許される。
    * Enumクラスは別のクラスを継承することはできませんが、インターフェースを実装することはできる。
* 以下のように記述して使う。
```
アクセス修飾子 enum 列挙名 {列挙子1, 列挙子2, ・・・};
```

#### どのような時に使うのか

* 決められた値に対して処理を行いたい場合に用いる。
  * enumの中に自身で決めた定数を記述でき、その値に対してswitch文などで処理を記述できることから。

#### サンプルコード

```
switch文を用いる場合
public class Main {
 
    public static void main(String[] args) {
        Fruit fruit_type = Fruit.Orange;
        
        switch(fruit_type) {
            case Orange:
                System.out.println("おいしいみかん");
                break;
            case Apple:
                System.out.println("りんごたべたい");
                break;
            case Melon:
                System.out.println("メロンがすべて");
                break;
        }
    }
    
    protected enum Fruit {
        Orange,
        Apple,
        Melon
    };
    
}
//実行結果
おいしいみかん

フィールドやメソッドを定義する場合
public class sample {
    public static void main(String[] args) {
        for(Fruit frt : Fruit.values()) {
            System.out.println(frt.ordinal() + ":" + frt.name() + "," + frt.getValue());
        }
    }
    protected enum Fruit {
        Orange("Ehime"),
        Apple("Aomori"),
        Melon("Ibaraki");
        
        // フィールドを定義
        private String name;
        
        // コンストラクタを定義
        private Fruit(String name) {
            this.name = name;
        }
        
        // メソッド
        public String getValue() {
            return this.name;
        }
    }
    
}
//実行結果
0:Orange,Ehime
1:Apple,Aomori
2:Melon,Ibaraki
```
### extends

* クラスの継承を行うための予約語。
* 継承元のクラスのことを「基底クラス」、「スーパークラス」、「親クラス」などと呼ぶ。
* 基底クラスを継承したクラスのことを「派生クラス」、「サブクラス」、「小クラス」などと呼ぶ。
  * 派生クラスでは、基底クラスの処理を変えたい場合にその処理のメソッド名や引数を変えることなく別の処理を記述することもできる。これをオーバーライドと呼ぶ。

#### どのような時に使うのか

* プログラミングするコードの量を少なくでき、ソースコードの可読性を高めることができる。
* 親クラスを定義することで他の子クラスで使うことができるので、コードをまとめて扱うことができる。

#### サンプルコード

```
public class Student{
　　String name;
　　int id;
　　attend(){}
}

public class School extends Student{
　　test(){}
}
```

### interface

* インターフェースを実装する際に使う予約語。
* インターフェースには定数とメソッドの定義しかできないというルールがある。

#### どのような時に使うのか

* インターフェースで定義した定数を定義したメソッドで使いまわせる。
* クラスの継承のように親クラスに定義したものを小クラスに定義すれば同じことであるが、クラスの継承との大きな違いは、クラスは一度に一つしか継承できないのに対して、インターフェースは1度に何個も実装することができる。その代わり、インターフェースを実装した先でインターフェースないに定義してあるメソッドを全て定義しなければならない。

#### サンプルコード

```
// インタフェースの作成
interface Calc {
    int NUM1 = 1;
    int NUM2 = 2;
 
    void calc();
}
 
// インタフェースを実装し、足し算するクラスを作成
class Add implements Calc {
    public void calc() {
        System.out.println(NUM1 + NUM2);
    }
}
 
// インタフェースを実装し、引き算するクラスを作成
class Sub implements Calc {
    public void calc() {
        System.out.println(NUM1 - NUM2);
    }
}
 
// インターフェースを実装したクラスを実行するクラスを作成
public class sample {
    public static void main(String[] args) {
        Add add = new Add();
        add.calc();
 
        Sub sub = new Sub();
        sub.calc();
    }
}
//実行結果
3
-1
```
### implements

* クラス定義の際にインターフェースの実装を行う際に使う予約語。

#### どのような時に使うのか

* インターフェースが定義してある前提で、それをクラスに実装させたい時に使う。

#### サンプルコード

```
public class Sample implements インターフェース名 {}
```

### private

* アクセス修飾子。
* アクセス修飾子とは：定義したクラスや、そのメンバーがどこからアクセスできるか、アクセスの制限をコントロールするもの。

#### どのような時に使うのか

* そのクラス内部からのみアクセス可能とする修飾子。

#### サンプルコード

```
class PublicClass {
    private String fieldVariable = "PublicClassのフィールド変数.";
    
    public void publicMethod() {
        System.out.println(fieldVariable + "publicMethodより出力.");
    }
}
 
public class sample {
 
    public static void main(String[] args) {
        PublicClass pc = new PublicClass();
        pc.publicMethod();
    }
 
}
//実行結果
PublicClassのフィールド変数.publicMethodより出力.
```

### protected

* アクセス修飾子。

#### どのような時に使うのか

* 同じパッケージ内のクラスや、違うパッケージでも、そのクラスを継承したサブクラス内部からアクセスすることを可能とするアクセス修飾子。

#### サンプルコード

```
//サブクラスから参照する場合
class SuperClass {
    protected String str = "SuperClassの変数";
}
 
public class sample extends SuperClass {
 
    public static void main(String[] args) {
        sample sc = new sample();
        System.out.println(sc.str);
    }
 
}
//実行結果
SuperClassの変数

//同一クラスから参照する場合
public class sample{
 
    public static void main(String[] args) {
        method();
    }
 
    protected static void method() {
        System.out.println("protectedが付いたメソッド");
    } 
}
//実行結果
protectedが付いたメソッド

//アクセスできない場合
class SuperClass {
    protected String str = "SuperClassの変数";
}
 
class SubClass_NG {
 
    public static void main(String[] args) {
        SubClass_NG sc = new SubClass_NG();
        System.out.println(sc.str);
    }
 
}
//実行結果
sample.java:9: エラー: シンボルを見つけられません
```

### public

* アクセス修飾子。

#### どのような時に使うのか

* どこからでもアクセス可能とする修飾子。
  * publicなクラス、インターフェースは1つのファイルに1つしか存在しない。
  * また、拡張子を除くファイル名とクラス名、インターフェース名は同じでないといけない。
  * パッケージ直下にあるクラス煮付けられるアクセス修飾子はpublicでないといけない。

#### サンプルコード

```
class PublicClass {
    public String fieldVariable = "PublicClassのフィールド変数.";
    
    public void publicMethod() {
        System.out.println(fieldVariable + "publicMethodより出力.");
    }
}
 
public class sample {
 
    public static void main(String[] args) {
        PublicClass pc = new PublicClass();
        System.out.println(pc.fieldVariable);
    }
 
}
//実行結果
PublicClassのフィールド変数.
```

### package

* パッケージの作成の宣言するための予約語。

#### どのような時に使うのか

* パッケージを宣言する際に用いる。
* パッケージとは：クラスやインターフェースをグループ化して分ける仕組み。
* 基本的にクラス名の重複は許されないが、パッケージが異なればクラス名が被っていても問題ない。
* そのため複数人での開発の際にクラス名が被ってもいいようにパッケージは使用する。

#### サンプルコード

```
package lang.java.hello;
 
public class HelloJava {
    public HelloJava() {
        System.out.println("Hello Java!");
    }
}
package lang.cpp.hello;
 
public class HelloCpp {
    public HelloCpp() {
        System.out.println("Hello C++!");
    }
}
```

### import

* パッケージをインポートするための予約語。

#### どのような時に使うのか

* パッケージをインポートする際に使用する。
* 以下のように記述する。
```
import パッケージ名.インポートしたいクラス名;
```
* パッケージ名の後に.*（ワイルドカード）をつけるとパッケージ内の全てのクラスをインポートできる。

#### サンプルコード

```
import lang.cpp.hello.HelloCpp;
import lang.java.hello.HelloJava;
 
public class Main {
 
    public static void main(String[] args) {
        HelloJava hello1 = new HelloJava();
        HelloCpp hello2 = new HelloCpp();
    }
 
}
```

### while

* 繰り返し処理を行うための構文。

#### どのような時に使うのか

* for文は繰り返し処理の回数指定ができるが、while文は回数指定が行われていない繰り返し処理を行い際に用いられる。

#### サンプルコード

```
public class sample {
    public static void main(String[] args) {
        int num = 0;
        while (num < 3) {
            System.out.println(num);
            num++;
        }
    }
}
//実行結果
0
1
2
```

### goto

* Javaにおいては無効な予約語。
* C言語/C++言語においては特定の行にジャンプするための予約語。

#### どのような時に使うのか

* 使えない。使った場合、コンパイルエラーとなる。

#### サンプルコード

* なし

### void

* 戻り値がないことを示す予約語。

#### どのような時に使うのか

* メソッドの戻り値がない場合に用いる。
* 戻り値とは：メソッドないの処理を実行して返される値のこと

#### サンプルコード

```
public class sample {

    static String sampleMethod() {
  
        //文字列を返却する
      return "サンプルメソッドが呼び出されました";
    }
  
    public static void main(String[] args) {
  
        //sampleMethodを呼び出し、その結果をstrという名前のString型変数に代入する
        String str = sampleMethod();
  
        //str変数の内容を出力する
      System.out.println(str);
    }
  }
//実行結果
サンプルメソッドが呼び出されました
```
### return

* 戻り値を返す時の予約語。

#### どのような時に使うのか

* 1.戻り値を返す場合。
* 2.メソッドの途中に使用されるとそれ以降の処理を実行せずに呼び出し元へ処理を戻す。

#### サンプルコード

```
//2の場合
public class sample {
 
	public static void main(String[] args) {
		num(0, 2);
	}
 
	private static void num(int num1, int num2) {
		if (num1 == 0) {
			System.out.println("呼び出し元に戻ります。");
			return;
		}
		int addAns = num1 + num2;
		System.out.println("答えは" + addAns + "です。");
	}
 
}
//実行結果
答えは2です。

//同じソースコードでreturnがない場合
public class sample {
 
	public static void main(String[] args) {
		num(0, 2);
	}
 
	private static void num(int num1, int num2) {
		if (num1 == 0) {
			System.out.println("呼び出し元に戻ります。");
			
		}
		int addAns = num1 + num2;
		System.out.println("答えは" + addAns + "です。");
	}
 
}
//実行結果
呼び出し元に戻ります。
答えは2です。
//解説
retuenがないので、if文の次の処理を行われた。
```
### new

* インスタンス化（オブジェクトの生成）を行える予約語。

#### どのような時に使うのか

* インスタンス化を行う際に用いる。
* クラスを元に生成するオブジェクトのこと
  * インスタンス化の際に同時実行されるものをコンストラクタという。
  * この中には初期化する処理を書く。

#### サンプルコード

```
public class メインクラス名{
    public static void main(String[] args) {

        //インスタンスの生成
        クラス名 変数名 = new クラス名();
    }
}

class クラス名{

    //コンストラクタ（インスタンス生成時に実行される）
    public クラス名(){
        初期化処理など
    }
}
```

### static

* クラスをインスタンス化せずに変数にアクセスできるようにするための予約語。

#### どのような時に使うのか

* クラス名.メソッド名();で呼び出すことができる。
* 呼び出すごとに毎回インスタンス生成して、初期化処理を行いたくない時。同じオブジェクトにアクセスしたい時に用いる。

#### サンプルコード

```
class ClassSample {
    private int val1 = 0; // 非static変数(インスタンス変数)
    private static int val2 = 0; // static変数(クラス変数)
 
    // コンストラクタ　クラスがインスタンス化される度に変数に1加算する
    public ClassSample(int val1, int val2) {
        this.val1 += val1;
        ClassSample.val2 += val2; // 「クラス名.変数名」でstatic変数を宣言
    }
 
    // 変数の値を表示
    public void print(){
        System.out.println("val1 = " + val1 + ", val2 = " + val2);
    }
}
 
public class sample {
 
    public static void main(String[] args) { 
        for (int i = 0; i < 3; i++){
            ClassSample cs = new ClassSample(1, 1);
            cs.print();
        }
    }
 
}
//実行結果
val1 = 1, val2 = 1
val1 = 1, val2 = 2
val1 = 1, val2 = 3
```

### final

* 定数を表す予約語。

#### どのような時に使うのか

* クラス、メソッド、変数にそれぞれ使用することができる。
  * 変数の場合：変数の値や、参照先を変更できなくする時に用いる。
    * finalとできる変数はローカル変数、引数、フィールド（インスタンス変数、クラス変数）の全て。
  * クラスの場合：そのクラスを継承できなくする時に用いる。
  * メソッドの場合：オーバーライドできなくする時に用いる。
  * 抽象クラス、インターフェースはfinalとはできない。
    * 継承や実装ができなくなってしまうため。

#### サンプルコード

```
//変数の場合
int x = 0; // 普通の変数宣言、初期値あり
x = 1;     // 変数の値を変更
 
final int y = 10; // 変数をfinalで宣言、初期値あり
y = 100;          // finalとした変数は変更できず、コンパイルエラー!!
 
String s = "A"; // 普通の参照型変数宣言、初期値あり
s = "B";        // 参照型変数の参照先を変更
 
final String s2 = "C"; // 参照型変数をfinalで宣言、初期値あり
s2 = "D";              // finalとした変数は変更できず、コンパイルエラー!!

//クラスの場合
final class FinalSample {
}
 
class ChildFinalSample extends FinalSample { // コンパイルエラー!! finalなクラスは継承できない
}

//メソッドの場合
class FinalSample {
 final void method() { // finalなインスタンスメソッド
 }
}
 
class ChildFinalSample extends FinalSample { // finalなクラスではないので継承はできる
 void method() { // コンパイルエラー!! finalなインスタンスメソッドはオーバーライドできない
 }
}
```
### _

* Javaでは無効な予約語。

#### どのような時に使うのか

* 使わない。

#### サンプルコード

* なし

### float

* 32bitで小数の値を表す基本データ型。

#### どのような時に使うのか

* 浮動小数で値を表現したい場合に用いる。
  * 浮動種数とは：計算で誤差が出ることを前提とした数値データのこと
* doubleとの違い：扱えるbit数の違い
  * double : 64bit | float : 32bit

#### サンプルコード

```
public class sample {
  public static void main(String[] args) {
    float f = 1.25f;
    int num = 10;
    float addNum = num + f;

    System.out.println(num + " + " + f + " = " + addNum);
  }
}
//実行結果
10 + 1.25 = 11.25
```
### int

* 32bitで整数を表す基本データ型。

#### どのような時に使うのか

* 整数なので、1ずつ増減する値を扱う。±21億くらいまでの整数を表現できる。
* intのリテラルの書き方
  * 2進数(“0b”で始まる、Java 7から)
  * 8進数(“0”で始まる)
  * 10進数(接頭語なし)
  * 16進数(“0x”で始まる)
* Integerとは
  * オブジェクト型なので、クラスとして扱う。
  * int型からString型へキャストしたい時に用いる。
  * nullを利用可能。

#### サンプルコード

```
int i1 = 123456789; // 10進数
int i2 = 0b1010101; // 2進数
int i3 = 012345670; // 8進数
int i4 = 0x123ABCDE; // 16進数
int i5 = 123_456_789; // 桁区切り(3桁ごと)
int i6 = 0b1111_1010_0101; // 桁区切り(4ビットごと)
```

### long

* 64bitで整数を表す基本データ型。

#### どのような時に使うのか

* int型では扱えない大きな数値を扱う時に用いる。
* int
  * 最大値：2^32-1
  * 最小値：-2^31
* long
  * 最大値：2^63-1
  * 最小値：-2^63

#### サンプルコード

```
public class sample {
    public static void main(String [] args) {
      int m = 2147483647;
      System.out.println(m);
      
      m += 1;
      System.out.println(m);
  
      long n = 2147483647;
      System.out.println(n);
    
      n += 1;
      System.out.println(n);
    }
  }
//実行結果
2147483647
-2147483648
2147483647
2147483648
```

### short

* 16bitで整数を表す基本データ型。

#### どのような時に使うのか

* -32768~32767の間の数値を扱う場合に用いる。
* 信用頻度としては高くない。
  * int > long > short
* short型で演算を行うと演算結果はint型で返されるため、int型の変数で値を受け取らないとコンパイルエラーになる。

#### サンプルコード

```
public class sample {
    short a=100;
    short b=10;
    short c=0;
    
    c = a + d;
    System.out.println("c =" + c );
  }
//実行結果
sample.java:6: エラー: <identifier>がありません
```

### instanceof

* 変数が参照しているクラスが正しいかどうかを判断する予約語。

#### どのような時に使うのか

* データの型を参照する時。
* サブクラスがスーパークラスを継承しているかを判定する時。
* インターフェースを実装しているかを判定する時。

#### サンプルコード

```
//データの型を参照する場合
public class sample {
    public static void main(String[] args) {
 
        Object obj = "samurai";
        System.out.println(obj instanceof String);
        System.out.println(obj instanceof Integer);
    }
}
//実行結果
true
false

//サブクラスがスパークラスを継承しているかを判定する場合
public class sample {
    public static void main(String[] args) {
 
        SubClass sub = new SubClass();
        System.out.println(sub instanceof SubClass);
        System.out.println(sub instanceof SuperClass);
    }
}
 
class SuperClass {}
class SubClass extends SuperClass{}
//実行結果
true
true

//インターフェースを実装しているかを判定する場合
public class sample {
    public static void main(String[] args) {
 
        SubClass sub = new SubClass();
        System.out.println(sub instanceof SubClass);
        System.out.println(sub instanceof Interface);
    }
}
 
interface Interface {}
class SuperClass implements Interface {}
class SubClass extends SuperClass {}
//実行結果
true
true
```
### this

* 自分自身を意味する予約語。

#### どのような時に使うのか

* 同じクラスのメソッドや変数を参照する場合。
* 別のコンストラクタを呼び出す場合。

#### サンプルコード

```
//同じクラスのメソッドや変数を参照する場合
public class sample {

    //Sampleクラス変数
    String animal = "うさぎ";

    public void printAnimal() {

      //ローカル変数
      String animal = "ねこ";
      System.out.println("ローカル変数animal:" + animal);
      System.out.println("クラス変数animal:" + this.animal);

    }

    public static void main(String[] args) {

        sample s = new sample();
        s.printAnimal();

      }
  }
//実効結果
ローカル変数animal:ねこ
クラス変数animal:うさぎ

//別のコンストラクタを呼び出す場合
class ThisSample8 {
    String name;
    int amount;
    
    // ①デフォルトコンストラクタ
    ThisSample8() {
    this("名無しの権兵衛", 10); // デフォルト値で③を呼び出す
    }
    
    // ②オーバーロードしたコンストラクタ(その1)
    ThisSample8(String name) {
    this(name, 20); // 引数を使いつつ、③を呼び出す
    }
    
    // ③オーバーロードしたコンストラクタ(その2)
    ThisSample8(String name, int amount) {
    // フィールドの初期化はこのコンストラクタだけで行う
    this.name = name;
    this.amount = amount;
    }
    
    void printProperty() {
    System.out.println(String.format("私の名前は%sです。所持金は%d円です。", name, amount));
    }
    
    public static void sample(String[] args) {
    ThisSample8 sample1 = new ThisSample8();
    sample1.printProperty(); // → 名無しの権兵衛、10円
    
    ThisSample8 sample2 = new ThisSample8("山田太郎");
    sample2.printProperty(); // → 山田太郎、20円
    
    ThisSample8 sample3 = new ThisSample8("鈴木次郎", 1000);
    sample3.printProperty(); // → 鈴木次郎、1000円
    }
   }
//実行結果
私の名前は名無しの権兵衛です。所持金は10円です。
私の名前は山田太郎です。所持金は20円です。
私の名前は鈴木次郎です。所持金は1000円です。
```

### super

* スーパークラスのインスタンスやメンバーを参照するための予約語。

#### どのような時に使うのか

* スーパークラスのコンストラクタを呼ぶ場合。
* オーバーライド前のメソッドを呼ぶ場合。

#### サンプルコード

```
//スーパークラスのコンストラクタを呼ぶ場合
public class sample {
    public static void main(String[] args) throws Exception {
        
        SubClass sub = new SubClass();
    }
}
 
class SuperClass {
 
    public SuperClass(){
        System.out.println("Super_Const");
    }
 
    public SuperClass(String str){
        System.out.println("str : " + str);
    }
    public SuperClass(int num){
        System.out.println("num : " + num);
    }
}
 
class SubClass extends SuperClass {
 
    public SubClass(){
        super("apple");
    }
}
//実行結果
str : apple
//オーバライド前のメソッドを呼ぶ場合
class SuperClassSample {
    String str = "SuperClass";
 
    public String getSrt() {
        return str;
    }
}
 
class SubClassSample extends SuperClassSample {
    String str = "SubClass";
 
    public String getSrt() {
        return str;
    }
 
    public void print() {
        System.out.println("super.str = " + super.str);
        System.out.println("str = " + str);
 
        System.out.println("super.getSrt() = " + super.getSrt());
        System.out.println("getSrt() = " + getSrt());
    }
}
 
public class sample {
    public static void main(String[] args) {
 
        SubClassSample scs = new SubClassSample();
        scs.print();
 
    }
}
//実行結果
super.str = SuperClass
str = SubClass
super.getSrt() = SuperClass
getSrt() = SubClass
```

### native

* Java以外の言語で記述されたメソッドを示す修飾子。

#### どのような時に使うのか

* JNI（java Native Interface）と呼ばれる、C/C++言語などのネイティブコードを連携させる仕組みがある。
* 実際にUCSのソースコードにも使われている。
* Javaファイルでインターフェースのようにメソッド名を定義する。
* cファイルにJNIEXPORTで定義すると、Javaファイルとcファイルが関連づけられる。
* Javaファイルで記述するメソッド名はcファイルで実際に処理しているメソッド名。

#### サンプルコード

```
//Javaファイル
pablic native boolean isCameraMute();

//cファイル
JNIEXPORT jboolean JNICALL プレフィックス_isCameraMute();
return isCsmeraMute();
```

### strictfp

* 浮動小数点をIEEE754という規格で決められたルールで厳密に処理するための予約語。
* クラス、インターフェース、メソッドは就職できるが、変数は修飾できない。

#### どのような時に使うのか

* IEEE（Institute of Electrical and Electronics Enginners）とは:アメリカに本部をおく、電気・情報工学分野の学術研究団体。技術標準化機関。
* IEEE754とは：浮動小数点に関する標準。32bitや64bitによって浮動小数点演算の誤差が違う計算をどの環境でも同じ結果にするために用いる。
* strictfpを用いない場合は、PCのCPUに依存して処理される。

#### サンプルコード

```
public class sample {
    public static void main(String args[]) {
        new sample();
    }
    //コンストラクタの生成
    public sample() {
        this.strictfpTest();
    }

    strictfp public void strictfpTest() {
        double a = 0.01;
        double b = 0.02;
        double c = 0.0001;

        System.out.println(a * b * c);
    }
}
//実行結果
2.0E-8
```

### synchronized

* 排他制御を行うための予約語。

#### どのような時に使うのか

* 排他制御を行い際に用いる。
* 排他制御とは：複数のプロセスが利用できる共有資源に対し、同時にアクセスすることを防ぐこと

#### サンプルコード

```
//synchronizedを用いない場合
public class sample{
    public static void main(String[] args) {
        Bathroom bathroom = new Bathroom();
        FamilyTread father = new FamilyTread(bathroom, "父");
        FamilyTread mother = new FamilyTread(bathroom, "母");
        FamilyTread sister = new FamilyTread(bathroom, "姉");
        FamilyTread me = new FamilyTread(bathroom, "私");

        father.start();
        mother.start();
        sister.start();
        me.start();
    }
}

class FamilyTread extends Thread {
    private Bathroom mBathroom;
    private String mName;

    FamilyTread(Bathroom bathroom, String name) {
        this.mBathroom = bathroom;
        this.mName = name;
    }

    public void run() {
        mBathroom.openDoor(mName);
    }

}

class Bathroom {
    void openDoor(String name) {
        System.out.println(name + "「お風呂に入ります！」");
        for (int count = 0; count < 100000; count++) {
            if (count == 1000) {
                System.out.println(name + "「お風呂に入りました。」");
            }
        }
        System.out.println(name + "「お風呂から出ました！」");
    }
}
//実行結果
父「お風呂に入ります！」
母「お風呂に入ります！」
父「お風呂に入りました。」
姉「お風呂に入ります！」
私「お風呂に入ります！」
母「お風呂に入りました。」
私「お風呂に入りました。」
姉「お風呂に入りました。」
父「お風呂から出ました！」
姉「お風呂から出ました！」
私「お風呂から出ました！」
母「お風呂から出ました！」

//class Bathroomにsynchronizedを用いた場合
class Bathroom {
    synchronized void openDoor(String name) {
        System.out.println(name + "「お風呂に入ります！」");
        for (int count = 0; count < 100000; count++) {
            if (count == 1000) {
                System.out.println(name + "「お風呂に入りました。」");
            }
        }
        System.out.println(name + "「お風呂から出ました！」");
    }
//実行結果
父「お風呂に入ります！」
父「お風呂に入りました。」
父「お風呂から出ました！」
私「お風呂に入ります！」
私「お風呂に入りました。」
私「お風呂から出ました！」
母「お風呂に入ります！」
母「お風呂に入りました。」
母「お風呂から出ました！」
姉「お風呂に入ります！」
姉「お風呂に入りました。」
姉「お風呂から出ました！」
```

### transient

* オブジェクトをシリアライズ対象外とする修飾子。

#### どのような時に使うのか

* シリアライズとは：オブジェクトの内容をファイルに保存したり、他のマシンに送信したりできるようにバイト配列に変換する事。
* Serializableインターフェースを実装するとデフォルトですべてのフィールドをシリアライズ対象とするが、その対象から除外したい時に用いる。
* 状態を保存する必要がない場合。
  * シリアライズしたものを復元する際に初期化したいフィールドが該当する。
* 直列化したいクラスに直列化不可能なフィールドがある場合。
* シリアライズするクラスのフィールドはプリミティブ型か、シリアライズ可能な型でないといけない。
  * シリアライズできないクラス：List,Map,Connection,InputStreamなど
  * シリアライズの入出力を実際に行うメソッド：write.Object()S

#### サンプルコード

```
//Main.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable;

public class Main { 
    public static void main(String[] args) throws Exception { 
        Player player = new Player(new Badminton()); 
        player.play();         System.out.println();

        Player clonePlayer = deepCopy(player); 
        clonePlayer.play(); 
        System.out.println();

        System.out.print("Playerのインスタンスが同じ："); 
        System.out.println(player == clonePlayer); 
        System.out.print("Badmintonのインスタンスが同じ："); 
        System.out.println(player.getSports() == clonePlayer.getSports()); 
    }

    @SuppressWarnings("unchecked") 
    public static <T extends Serializable> T deepCopy(T t) throws Exception { 
        if (t == null) { 
            return null; 
        }

        ByteArrayOutputStream byteOut = null; 
        ObjectOutputStream objectOut = null; 
        try { 
            byteOut = new ByteArrayOutputStream(); 
            objectOut = new ObjectOutputStream(byteOut); 
            objectOut.writeObject(t); 
        } finally { 
            objectOut.close(); 
        }

        ObjectInputStream objectin = null; 
        T copy = null; 
        try { 
            objectin = new ObjectInputStream(new ByteArrayInputStream
                                                     (byteOut.toByteArray())); 
            copy = (T) objectin.readObject(); 
        } finally { 
            objectin.close(); 
        } 
        return copy; 
    } 

}

//Sports.java
public interface Sports { 
    void play(); 
}

class Badminton implements Sports { 
    @Override 
    public void play() { 
        System.out.println("バドミントンして遊びます。"); 
    } 
}

//Player.java
import java.io.Serializable;

@SuppressWarnings("serial") 
public class Player implements Serializable { 
    private transient Sports sports;

    public Player(Sports sports) { 
        this.sports = sports; 
        System.out.println("コンストラクタです。"); 
    }

    public Sports getSports() { 
        return sports;    
 }
 public void play() { 
        System.out.println("ウォームアップします。");

        sports.play();

        System.out.println("クールダウンします。"); 
    } 
}
```

### volatile

* 共有メモリと各スレッドの変数の値を一致させる修飾子。

#### どのような時に使うのか

* フィールドの値のキャッシュを抑制する場合。
  * マルチスレッドの場合、それぞれのスレッドが同じフィールの値をキャッシュすることがある。この時、同じフィールドでも値が異なってくる危険性がある。
  * キャッシュとは：メインメモリとは違う場所に値を誇示する事で、一般的にメモリに比べて保存量は少ないが、高速に値の呼び出しや、更新が行える。
* コンパイラで最適化されるのを防ぐ場合。
  * コンパイラとは：人間にわかりやすく、複雑な機能や構文を持つ高水準プログラミング（CやJavaなど）で書かれたコンピュータープログラムをコンピュータが解釈・実行できる形式に一括して変換するソフトウェア。

#### サンプルコード

```
public class VolatileSample {
 
    private static volatile int count = 0;
    //private static int count = 0;
 
    public static void main(String[] args) {
        new MultiThread1().start();
        new MultiThread2().start();
    }
 
    static class MultiThread1 extends Thread {
        public void run() {
            int val = count;
            while(count < 3) {
                if (val != count) {
                    String message = getName() + ": val = " + val + ", count = " + count;
                    System.out.println(message + " 更新");
                    val = count;
                }
            }
        }
    }
 
    static class MultiThread2 extends Thread {
        public void run() {
            int val = count;
            while(count < 3) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String message = getName() + ": val = " + val + ", count = " + count;
                System.out.println(message);
                count = ++val;
            }
        }
    }
}
//実行結果
Thread-1: val = 0, count = 0
Thread-0: val = 0, count = 1 更新
Thread-1: val = 1, count = 1
Thread-0: val = 1, count = 2 更新
Thread-1: val = 2, count = 2
```