Java11 Gold 資格 学習

Java 11 Silver & Gold 受験対策 & 今後の備忘録
# 型
Javaのデータ型には**プリミティブ型**と**参照型**がある。

参照型には更にクラス型、配列型、列挙型などの分類がある。

- プリミティブ型 
    - boolean 
    - char
    - byte
    - short
    - int
    - long
    - float
    - double
- 参照型
    - クラス型
    - インターフェース型
    - 配列型
    - 列挙型


## プリミティブ型
| 型 | サイズ | 説明 | 値 | ラッパー |
|:-:|:-:|:-:|:-:|:-:|
| `boolean` | 仕様無 | 真偽値 | `true`, `false` | `Byte` |
| `char` | 16bit | Unicode文字 | `¥u0000` ~ `¥uFFFF` | `Character` |
| `byte` | 8bit | 整数 | `-128` ~ `127` | `Byte` |
| `short` | 16bit | 整数 | `-32768` ~ `32767` | `Short` |
| `int` | 32bit | 整数 | `-2137383648` ~ `2147483647` | `Integer` |
| `long` | 64bit | 整数 | `-9223372036854775808` ~ `9223372036854775807` | `Long` |
| `float` | 32bit | 単精度浮動小数点数 | `±3.40282347E+38` ~ `1.40239846E-45` | `Float` |
| `double` | 64bit | 倍精度浮動小数点数 | `±1.79769313486231570E+308` ～ `±4.94065645841246544E-324` | `Double` |

:::note info
**`String`型はプリミティブ型ではなく参照型**。
:::

## 参照型
クラス型、配列型、列挙型がある。

# リテラル

## 整数リテラル

デフォルトでは`int`型として扱われる。

整数リテラルを`long`型として扱いたい場合、末尾に`l`もしくは`L`の接尾辞をつける。
```java
long a = 100L;
```

また整数リテラルを`short`型や`byte`型として扱うための接尾辞は存在しない。その代わりに`int`型と`short`型などは自動変換される。

```java
// 10はint型として扱われる整数リテラルだが、short型に代入できる（short型に自動変換される）
short i = 10;
```

### 10進数、2進数、8進数、16進数
デフォルトでは10進数として扱われる。

2進数で表したい場合、`0b`を接尾辞としてつける。
```java
byte ichi = 0b0001;  // 1
short ni = 0b0010;   // 2
int san = 0b00011;   // 3

System.out.println(ichi);
System.out.println(ni);
System.out.println(san);
// >> 1
// >> 2
// >> 3
```

8進数で表したい場合、`0`を接尾辞としてつける。

```java
byte nana = 07;     // 7
short hachi = 010;  // 8
int kyu = 011;      // 9

System.out.println(nana);
System.out.println(hachi);
System.out.println(kyu);
// >> 7
// >> 8
// >> 9
```

16進数で表したい場合、`0x`を接尾辞としてつける。

```java
byte jugo = 0xF;     // 15
short juroku = 0x10; // 16
int junana = 0x11;   // 17

System.out.println(jugo);
System.out.println(juroku);
System.out.println(junana);
// >> 15
// >> 16
// >> 17
```

## 浮動小数点数リテラル
デフォルトでは`double`型として扱われる。

`float`型として扱いたい場合、末尾に`f`もしくは`F`の接尾辞をつける。
```java
float a = 100.0F;
```
## 真偽リテラル
`boolean`型として扱われる。

## 文字リテラル
`char`型として扱われる。

文字リテラルは**シングルコーテーション**（`'`）で囲う必要がある。

またJavaは **Unicode** を文字コードとして採用していて、Unicodeエスケープシーケンスを使って文字を表現する際には**バックスラッシュ**（`\`）を使用する。（Windows環境では`¥`）

Unicode の文字は `U+0000` ~ `U+FFFF`までの文字コードが存在するが、Javaでは`\u0000` ~ `\uFFFF`で表現する。

```java
char komoji = '\u0061';
char omoji = '\u0041';

System.out.println(komoji);
System.out.println(omoji);
// >> a
// >> A
```

文字リテラルは直接16進数や10進数でも表現できる。（`0x0000` ~ `0xFFFF` は10進数では `0` ~ `65535`であるため、次のような表現も可能。

```java
char komoji = 0x0061;
char komoji2 = 97; // 0x0061 = 97

char omoji = 0x0041;
char omoji2 = 65; // 0x0041 = 65

System.out.println(komoji);
System.out.println(komoji2);
// >> a
// >> a

System.out.println(omoji);
System.out.println(omoji2);
// >> A
// >> A
```

`char`型の変数に文字列リテラルは代入できない。

```java
char ok = 'a'; // 有効
char error = "a"; // コンパイルエラー
```

:::note info
Javaはシングルコーテーションとダブルコーテーションに明確な違いがあるため注意。
:::


## 文字列リテラル

`String`型として扱われる。

文字列リテラルは**ダブルコーテーション**（`"`）で囲う必要がある。


## `String`型

`String`型はプリミティブ型ではなく参照型（`java.lang.String`）に分類される。

`String`クラスは内部で文字列を`char`型の配列として扱っている。

`String`型はインターフェース`CharSequence`の実装クラスでもある。


### `String`型のインスタンス化

参照型のデータ型は`new`演算子によってインスタンス化を行う。

```java
MyClass a = new MyClass();
```

ただし、`String`型だけは特別扱いで、文字列リテラルによって`String`型のインスタンスが生成できるようになっている。

```java
String a = "hello world"; // String型はプリミティブ型ではなく参照型
```

### immutable

`String`クラスは **immutable** なクラスであるため、一度生成したインスタンスは中身を変更することができない。

`String`型変数への再代入は、インスタンスの中身変更ではなく実際にはインスタンス新規生成を意味する。

```java
// インスタンスに変更を加えているように見えるが、実際にはインスタンスを変更している訳ではない
String a;
a = "hello world";
a = "ABCD";
```

```java
// 実際は immutable なインスタンスを新規生成している
String a;
a = new String("hello world");
a = new String("ABCD");
```

このため、`subString()`、`concat()`、`toUpperCase()`などのメソッドが返すインスタンスは、実行されたメソッドのインスタンスではなく、新しいインスタンスということになる。


### コンスタントプール

前述の通り、「文字列リテラルの使用」は「`java.lang.String`クラスのインスタンス生成」を意味する。

しかし実際の文字列リテラルは、同じものが頻繁に使用されることが多い。同じ文字列であるのにわざわざ別のインスタンスとして扱うメリットはなく、逆に新たなインスタンス生成の度にメモリ領域が必要になってしまい非常に非効率になる。

```java
String a = "hello world";
String b = "hello world";
String c = "hello world";
String d = "hello world";
```

そのため文字列リテラルには**コンスタントプール**という仕組みがある。

コンスタントプールは文字列リテラルから生成された`String`インスタンスを管理するためのメモリ領域のことを指す。

通常、文字列リテラルが使用されるとまず最初に定数用のメモリ空間（コンスタントプール）にその文字列リテラルから生成されたインスタンスが既に存在しないかがチェックされる。存在しない場合に限り、`String`型インスタンスが生成され、生成されたインスタンスがコンスタントプールに配置される。

この仕組みにより、同じ文字列リテラルから`String`型インスタンスを生成する際は、過去に生成された`String`インスタンスへの参照が再利用される。

```java
// 同じインスタンスへの参照が再利用されていることがわかる
String a = "hello world"; // コンスタントプール生成
String b = "hello world"; // コンスタントプールに存在するインスタンスへの参照を再利用
String c = "hello world"; // コンスタントプールに存在するインスタンスへの参照を再利用
String d = "hello world"; // コンスタントプールに存在するインスタンスへの参照を再利用

if (a == b && b == c && c == d) {
    System.out.println("各変数は同じインスタンスを参照している");
}
// >> 各変数は同じインスタンスを参照している
```

ただし、プログラムの中で動的に生成された文字列はコンスタントプールに配置されない。また明示的に`new`演算子によって生成されたインスタンスが生成された場合、`String`インスタンスはコンスタントプールからの再利用は行われない。

`String`クラスの`intern()`メソッドは、コンスタントプール（を含むメモリ領域）内から`String`インスタンスを検索してその参照を返すことができる。

```java
String a = "hello world";
// 明示的にnewしているので、コンスタントプールからのインスタンスの再利用、またはコンスタントプールへの保存がされない
String b =  new String("hello world");

if (a == b) {
    System.out.println("同じインスタンスを参照している");
}else{
    System.out.println("別のインスタンスを参照している");
}
// >> 別のインスタンスを参照している

if (a == b.intern()) {
    System.out.println("同じインスタンスを参照している");
}else{
    System.out.println("別のインスタンスを参照している");
}
// >> 同じインスタンスを参照している
```

## 初期値

クラスのフィールドは、デフォルトで初期化されるため、`int`型のメンバ変数は`0`、`boolean`型は`false`、参照型のメンバ変数は`null`に初期化される。

一方メソッド内のローカル変数は、明示的に初期化されない限り初期値が設定されない。
```java
class MyClass {
    int a; // 0に初期化される
    boolean b; // falseに初期化される
    String c; // nullに初期化される

    void myMethod() {
        int x; // 初期化されない
        System.out.println(x); // コンパイルエラー
    }
}
```

## 型推論・ジェネリクス・共変性・反変性

https://qiita.com/AsahinaKei/items/79299c771964ae6b7308


# 初期化子（Initializer）
クラスの初期化時に特定のコードを実行するための特殊なブロックのこと。

**static初期化子**（static initializer）と**インスタンス初期化子**（instance initializer）がある。

### static初期化子
クラスがロードされるときに一度だけ実行されるコードブロック。

```java
class MyClass {
    static {
        System.out.println("hello world");
    }
}
```

静的なフィールドを初期化する際に有効。
```java
class MyClass {
    static int a;
    
    static {
        a = 10;
    }
}
```

### インスタンス初期化子
インスタンス生成の度に実行されるコードブロック。

コンストラクタの前に実行される。

```java
class MyClass {
    {
        System.out.println("hello world");
    }
}
```

オーバーロードによるコンストラクタが複数あるような場合に、全てのコンストラクタに共通の処理をまとめたい時などに有効。


```java
class MyClass {
    {
        // コンストラクタの前に実行される
        System.out.println("共通処理");
    }

    MyClass(int a) {
        System.out.println("コンストラクタ1");
    }

    MyClass(int a, int b) {
        System.out.println("コンストラクタ2");
    }
}
```

### 実行順

1. スーパークラスのstatic初期化子
2. サブクラスのstatic初期化子
3. スーパークラスのインスタンス初期化子
4. スーパークラスのコンストラクタ
5. サブクラスのインスタンス初期化子
6. サブクラスのコンストラクタ
```java:SuperClass
class SuperClass {
    static {
       System.out.println("①static initializer of super class");
    }

    {
        System.out.println("③instance initializer of super class");
    }

    SuperClass(){
        System.out.println("④constructor of super class");
    }
}
```
```java:SubClass
class SubClass extends SuperClass{
    static {
        System.out.println("②static initializer of sub class");
    }

    {
        System.out.println("⑤instance initializer of sub class");
    }

    SubClass(){
        System.out.println("⑥constructor of sub class");
    }
}
```

```java:実行順
SuperClass a = new SubClass();
// >> ①static initializer of super class
// >> ②static initializer of sub class
// >> ③instance initializer of super class
// >> ④constructor of super class
// >> ⑤instance initializer of sub class
// >> ⑥constructor of sub class
```



# ネストしたクラス

https://qiita.com/AsahinaKei/items/32e5c97740814ba6f3a5

# ストリーム

https://qiita.com/AsahinaKei/items/7ba294a97d2da67ddf2a

# 入出力

https://qiita.com/AsahinaKei/items/5f62d67576b2d221d077

# JBDC

https://qiita.com/AsahinaKei/items/e0067183ccbc78bb3b77

# アノテーション

https://qiita.com/AsahinaKei/items/75c59fe2145ca4c31c49

# Enum

JavaのEnumはクラス。

定義したEnumは`java.lang.Enum`クラスのサブクラスとして扱われる。

定義した列挙子は、それぞれが列挙型から生成されたインスタンスとして扱われる。

```java
public enum Fruits {
    Apple, // Fruits型インスタンス
    Banana, // Fruits型インスタンス
    Orange, // Fruits型インスタンス
}
```

コンストラクタやフィールドを定義する事ができる。ただし、コンストラクタは`private`でなけらばならず、省略した場合には暗黙的に`private`と解釈される。明示的に`public`とした場合、コンパイルエラーが発生する。

```java
public enum Fruits {
    Apple(1), // Fruits型インスタンス
    Banana(2), // Fruits型インスタンス
    Orange(3); // Fruits型インスタンス
    
    private int id;

    // privateと解釈される
    Fruits(int id){
        this.id = id;
    } 
}
```

# ローカライズ

https://qiita.com/AsahinaKei/items/ae5a6c53f12abafa2e93

# プロパティファイル

https://qiita.com/AsahinaKei/items/93e50eee48e317814fbd

# 例外

![Error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/8e8546a3-9182-1afb-e19b-121569d4c6db.png)


## アサーション

アサーションの構文は以下の通り。


```java:アサーション
assert 条件式 : "メッセージ";
```

アサーションはでフォルドでは無効になっているため、実行時に`-ea`オプションをつける必要がある。

```console:
$ java -ea com.sample.app.Main
```

# モジュールシステム

https://qiita.com/AsahinaKei/items/cf31cfd1276b7724ebf7

# 試験対策としての早見表
文法的な暗記系知識。

## 実行

#### 起動パラメータにスペースを含めたい場合、ダブルコーテーション「`"`」で囲う

```shell:起動パラメータにスペースを含めたい場合、ダブルコーテーション「"」で囲う
java Main.java "hello world"
```

#### 起動パラメータにダブルコーテーション「`"`」を使いたい場合、エスケープする

LinuxOSの場合はバックスラッシュ「`\`」、Windowsの場合は「`¥`」を使用する
```shell:起動パラメータにダブルコーテーション「"」を使いたい場合、エスケープする
java Main.java \"
```
上の例では「"」がパラメータとして渡される。

#### エスケープされないダブルコーテーション「`"`」は無視される

```shell:エスケープされないダブルコーテーション「"」は無視される
java Main.java a"bc"
```
上の例では「abc」がパラメータとして渡される。


## アクセス修飾子
#### `protected`とデフォルトの違いに注意して覚える
| 修飾子 | 可視性 |  |
|:-:|:-:|:-:|
| private | - | 同じクラス内からのみ |
| なし（デフォルト） | ~ | **同じパッケージ内**からのみ |
| protected | # | **同じパッケージ内**　+　継承関係にあるサブクラス　からのみ |
| public | + | 全て |

## for文

#### 初期化文と更新文はコンマ（`,`）で区切って複数記述することができる

```java:初期化文と更新文はコンマ（,）で区切って複数記述することができる
for (int i = 0, j = 0; i < 10; i++, j--) {
    // 処理 
}
```

ただし初期化では同じ型しか記述できない
```java:コンパイルエラー
// コンパイルエラー
for (int i = 0, long j = 0; i < 10; i++, j--) {
    // 処理 
}
```

#### 条件式と更新式は省略できる

```java:条件式を省略した場合
for (int i = 0; ; i++) {
    // 処理
}
```

```java:更新式を省略した場合
for (int i = 0; i < 10; ) {
    // 処理
}
```

#### `break`で抜けるのは直近のループだけ

```java:breakで抜けるのは直近のループだけ
 for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if(条件){
           braek; 
        }
    }
    // ここに抜ける
}
// ここには抜けない
```

## switch文

:::note alert
switch文の条件式には`boolean`型や`long`型、`float`型、`double`型を使用することができない。
参照型（`String`型と列挙型を除く）についても使用することができない。
:::

#### `fianl`ではない変数は`case`に使用できない

```java:fianlではない変数はcaseに使用できない
int target = 100;
int a = 10;
final int B = 10;

switch (target) {
    case B:
        // 処理
        break;
    case a: // コンパイルエラー
        // 処理
        break;
}
```

## 配列

#### 要素数は必ず右辺に書く
配列宣言時に左辺の型として使用する配列型（`int[]`や　`int[][]`など）は配列オブジェクトへの参照を保持するためのものであり、配列の要素数については関与しない。

各要素については配列オブジェクトが管理を行う。

```java:要素数は必ず右辺に書く
int[] array = new int[10];

// コンパイルエラー
int[10] array = new int[];

// コンパイルエラー
int[10] array = new int[10];
```

#### `[]`は変数名の後ろにも置ける

```java:[]は変数名の後ろにも置ける
int[] array = new int[10];

int array2[] = new int[10];

int array3[][] = new int[10][20];
```

#### 多次元配列は`[]`をデータ型の後ろと変数名の後ろに分散して置ける

```java:多次元配列は[]をデータ型の後ろと変数名の後ろに分散して置ける
int[] array2[] = new int[10][20];  // 2次元配列

int[][] array3[] = new int[10][20][30]; // 3次元配列
```

#### 多次元配列の1次元目の要素数は省略できない

```java:多次元配列の1次元目の要素数は省略できない
int[][] array = new int[10][20];

int[][] array2 = new int[10][];

// コンパイルエラー
int[][] array3 = new int[][20];        
```

#### 多次元配列の2次元目以降は要素数を揃える必要はない

```java:多次元配列の2次元目以降は要素数を揃える必要はない
int[][] array = new int[3][];

array[0] = new int[10];
array[1]= new int[20];
array[2] = new int[30];
```

#### 配列の初期子`{}`を使用する場合、要素数は指定できない

```java:配列の初期子{}を使用する場合、要素数は指定できない
int[] array = {1, 2, 3, 4, 5};

int[] array2 = new int[]{1, 2, 3, 4, 5};

// コンパイルエラー
int[] array3 = new int[5]{ 1, 2, 3, 4, 5};
```

#### 明示的に初期化しなかった配列の各要素は、型のデフォルト値になる

```java:明示的に初期化しなかった配列の各要素は、型のデフォルト値になる
int[] a = new int[1];
System.out.println(a[0]);
// >> 0

double[] b = new double[1];
System.out.println(b[0]);
// >> 0.0

boolean[] c = new boolean[1];
System.out.println(c[0]);
// >> false

char[] d = new char[1];
System.out.println(d[0]); // \u0000
System.out.println((int)d[0]);
// >> 
// >> 0

String[] e = new String[1];
System.out.println(e[0]);
// >> null

Object[] f = new Object[1];
System.out.println(f[0]);
// >> null
```



## コンストラクタ

#### コンストラクタに見えるメソッド

```java:コンストラクタに見えるメソッド
class MyClass {
    // 戻り値を指定しているためコンストラクタ扱いにならず、メソッド扱いになる
    void MyClass(){
        System.out.println("hello world");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass a = new MyClass();
        a.MyClass();
        // >> hello world
    }
}
```

#### 自身のコンストラクタは`this()`で呼び出せる

```java:自身のコンストラクタはthis()で呼び出せる
class MyClass {
    MyClass() {
        this(10);
    }

    MyClass(int a) {
    
    }
}
```

#### 自身のコンストラクタを呼び出す場合、thisより前に処理は実行できない
```java:自身のコンストラクタはthisで呼び出せる
class MyClass {
    MyClass() {
        // thisは最初に実行しなければならない
        System.out.println("hello world");
        // コンパイルエラー
        this(10);
    }

    MyClass(int a) {
    
    }
}
```

## インターフェース

#### `final`かつ`static`なフィールドなら定義できる

```java:finalかつstaticなフィールドなら定義できる
interface MyInterface {
    public static final int A_MAX = 10;
}
```

以下のように記述することも可能。
```java
interface MuInterface {
    // 内部的には　public static final int A_MAX = 10;　として扱われる
    int A_MAX = 10;
}
```

#### `static`なメソッドも定義できる

```java:staticなメソッドも定義できる
interface MyInterface {
    public static void myMethod(){
        
    };
}
```

#### `private`なメソッドも定義できる

```java:privateなメソッドも定義できる
public interface MyInterface {
    private void method() {
        System.out.println("hello world");
    }
}
```

複数の`default`メソッドの共通処理をまとめる事ができる。

#### `Object`クラスのメソッドをオーバーライドできない
インターフェースは通常、中身のない抽象メソッドのみが定義可能であり、中身のあるメソッドを定義する場合`default`を使用する必要がある。
```java
interface MyInterface {
    public void myMethodA();

    default public void myMethodB() {
        System.out.println("hello world");
    }

    // コンパイルエラー
    public void myMethodC() {
        System.out.println("hello world");
    }
}
```

この`default`を使用してメソッドの定義をするとき、`java.lang.Object`のメソッド（`equals()`, `hashCode()`, `toString()`）をオーバーライドすることはできない。

```java:Objectクラスのメソッドをオーバーライドできない
interface MyInterface {
    // コンパイルエラー
    @Override
    default public String toString() {
        return "hello world";
    }
}
```

#### インターフェースの`default`メソッドを呼び出す

次の構文でインターフェースの`default`メソッドを実装クラスから呼び出す事ができる。

```java
インターフェース名.super.メソッド名()
```

```java:スーパークラスのdefaultメソッドを呼び出す
interface MyInterface {
    default public void a() {
        System.out.println("hello world");
    }
}

class ConcreteClass implements MyInterface {
    @Override
    public void a() {
        // インターフェース名.super.メソッド名()
        MyInterface.super.a();
        System.out.println("hello world");
    }
}
```

ただし、直接実装（`implements`）していないスーパークラスの`default`メソッドは呼び出せない（孫から祖父母のメソッドは呼べない）。

```java:直接実装（implements）していないスーパークラスのdefaultメソッドは呼び出せない
interface SuperInterface {
    default public void a() {
        System.out.println("hello world");
    }
}

interface SubInterface extends SuperInterface {   
}

class ConcreteClass implements SubInterface {
    @Override
    public void a() {
        // コンパイルエラー
        SuperInterface.super.a();
        System.out.println("hello world");
    }
}
```

「もしインターフェース名を指定しなくても良い」とすると、多重に実装（`implements`）したインターフェースに同じ名前の`default`メソッドが定義されていたらどちらのメソッドかが判別できなくなってしまう。


```java:もしインターフェース名を指定しなくてもよかったら
interface InterfaceA {
    default public void hello() {
        System.out.println("hello world");
    }
}

interface InterfaceB {
    default public void hello() {
        System.out.println("hello world");
    }
}

class ConcreteClass implements InterfaceA, InterfaceB {
    @Override
    public void hello() {
        // コンパイルエラー（どっちのhello()？）
        super.hello();
        System.out.println("hello world");
    }
}
```

#### `default`メソッド　>　通常メソッド

インタフェースの本来の目的は「型を提供すること」であり、`default`メソッドはあくまでもオプション的な位置付けであるため、同じ名前のメソッドがインターフェースとスーパークラス両方で定義されている場合、スーパークラスのメソッドが優先される。

```java
public interface MyInterface {
    default void method() {
        System.out.println("インターフェース");
    }
}
```

```java
public class SuperClass {
    public void method() {
        System.out.println("スーパークラス");
    }
}
```

```java
public class MyClass extends SuperClass implements MyInterface {}
```


```java
MyClass obj1 = new MyClass();
obj1.method();
// >> スーパークラス

SuperClass obj2 = new MyClass();
obj2.method();
// >> スーパークラス

MyInterface obj3 = new MyClass();
obj3.method();
// >> スーパークラス
```

## 継承

#### サブクラスではスーパークラスのフィールド名と同じフィールド名を使える

サブクラスではスーパークラスのフィールド名と同じフィールド名を使える。（オーバーライドではなく、実際には新しいフィールドが追加される）

ただし、実行時どちらにアクセスされるかは変数の宣言型に依存する。スーパークラス型で宣言した変数を通してアクセスを行った場合にはスーパークラスで宣言したフィールドが使用される。

```java:同じ名前のフィールドが存在する場合
class SuperClass {
    String a = "super";
}

class SubClass extends SuperClass {
    String a = "sub";
}
```

```java:実行時のアクセスは変数の宣言型に依存する
SuperClass obj1 = new SubClass();
System.out.println(obj1.a);
// >> super

SubClass obj2 = new SubClass();
System.out.println(obj2.a);
// >> sub
```

メソッドからのアクセスの場合、以下のようになる。

```java:メソッドを通じたアクセス　~パターン1~
class SuperClass {
    String a = "super";

    public void b() {
        System.out.println(a);
    }
}

class SubClass extends SuperClass {
    String a = "sub";
}
```

```java:メソッドの所有者のフィールドが使用される　~パターン1~
SuperClass obj1 = new SubClass();
obj1.b();
// >> super

SubClass obj2 = new SubClass();
obj2.b();
// >> super
```


```java:メソッドを通じたアクセス　~パターン2~
class SuperClass {
    String a = "super";

    public void b() {
        System.out.println(a);
    }
}

class SubClass extends SuperClass {
    String a = "sub";

    // オーバーライドしている
    @Override 
    public void b() {
        System.out.println(a);
    }
}
```

```java:メソッドの所有者のフィールドが使用される　~パターン2~
SuperClass obj1 = new SubClass();
obj1.b(); // オーバーライドしているためSubClassのメソッドが使用される
// >> sub

SubClass obj2 = new SubClass();
obj2.b();
// >> sub
```

#### スーパークラスのコンストラクタはコンパイル時に自動で追加される

```java:スーパークラスのコンストラクタはコンパイル時に自動で追加される
class SuperClass {
    public SuperClass() {
        System.out.println("super class constructor");
    }
}

class SubClass extends SuperClass {
    public SubClass() {
        // コンパイル時にここに super(); が自動挿入される
        System.out.println("sub class constructor");
    }
}
```

```java:
SuperClass obj = new SubClass();
// >> super class constructor
// >> sub class constructor
```

#### 継承させたくないクラスは`final`で修飾する

```java:継承させたくないクラスは final で修飾する
final class myClass {
    
} 
```


#### `Object`の`equals()`

`Object`の`equals()`はオーバーライドして**同値性**を検証させるものだが、オーバーライドをしなかった場合には**同一性**（`==`と同じ）を検証するようになっている。

#### `static`メソッドはオーバーライドできない

```java:staticメソッドはオーバーライドできない
public class SuperClass {
    static void method() {
    }
}
```

```java
public class SubClass extends SuperClass {
    // コンパイルエラー
    @Override
    static void method() {
    }
}
```

ただし`@Override`アノテーションをつけなかった場合、スーパークラスの`static`メソッドを隠蔽したことになり、コンパイルエラーが起きない。

```java
public class SubClass extends SuperClass {
    // 親クラスのメソッドを隠蔽
    static void method() {
    }
}
```

## 関数型インターフェース・ラムダ式
基本事項はこちら。

https://qiita.com/AsahinaKei/items/b05b5b59e94840cbbaa1

#### ラムダ式内で利用するローカル変数は実質的に`final`でなければならない

ラムダ式は宣言場所と同じスコープを持つため、ラムダ式内でラムダ式を宣言したスコープからアクセス可能なローカル変数にアクセスすることができる。

一方で、ラムダ式が実行されるのは宣言場所と別のタイミングになるため、ラムダ式内でローカル変数へのアクセスを行うと、そのローカル変数は実質的に`final`（effectively final）でなければならなくなる。

```java:ラムダ式内で利用するローカル変数は実質的にfinalでなければならない
String a = "hello";

// ラムダ式内で a を参照
Runnable runnable = () -> System.out.println(a);

// aに再代入しようとするとコンパイルエラーが起きる
a = "Goodbye";

runnable.run();
```

## 関数型インターフェース 早見表

| インターフェース名 | 定義 | 補足 |
|-:|-:|-:|
| `Supplier<T>` | `T get();` |  |
| `Consumer<T>` | `void accept(T t);` |  |
| `BiConsumer<T, U>`  | `void accept(T t, U u);` |  |
| `Predicate<T>` | `bolean test(T t);` |  |
| `BiPredicate<T, U>` | `boolean test(T t, U u);` |  |
| `Function<T>` | `R apply(T t);` |  |
| `BiFunction<T, U>` | `R apply(T t, U u);` |  |
| `UnaryOperator<T>` | `T apply(T t);` |  |
| `BinaryOperator<T>` | `T apply(T t1, T t2);` | `BiFunction<T, U>`の`T`と`U`が同じパターン。<br>`BiFunction<T, U>`の特殊系と言う位置づけ。 |
| `Runnabale` | `void run();` |  |
| `Callable<V>` | `V call();` |  |


## コレクション

#### `Arrays.asList()`が返す`List`は固定サイズ

配列を`List`に変換することができる`Arrays.asList()`が返す`List`は、要素数が固定の特殊な`List`になっている。

通常の`List`と同じだと勘違いして要素を追加しようとすると、実行時例外が発生する。

```java:Arrays.asList() が返す List は固定サイズ
List<String> list = Arrays.asList(new String[]{"aaa", "bbb", "ccc"});
list.add("ddd"); // 実行時例外が発生する
```

要素数が固定の`List`は明示的に生成することも可能。
```java
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");

// 要素数が固定のListに変換
List<String> list2 = Collections.unmodifiableList(list);

list2.add("ddd"); // 実行時例外が発生する
```

動的サイズの`ArrayList`を初期化したい場合、`ArrayList`のコンストラクタに固定サイズの`List`を渡す。

```java:
List<String> list = new ArrayList<>(
        Arrays.asList(new String[]{"aaa", "bbb", "ccc"})
);
list.add("ddd");
```

## 並列処理

#### 暗記系クラス名とメソッド名

![Executor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/26e6ef24-aca3-fec3-389d-1e739268a285.png)


## API

#### 累乗は`pow`、平方根は`sqrt`

**pow** : power（累乗）

```java:power（累乗）
// x の y 乗
Math.pow(x, y)
```

**sqrt**: square root（平方根）

```java: square root（平方根）
// x の平方根
Math.sqrt(x)
```

## try-catch / try-with-resources

#### `catch`と`finally`ブロックでどちらも戻り値を`return`したときは`finally`の戻り値が優先される

```java:catchとfinallyブロックでどちらも戻り値をreturnしたときはfinallyの戻り値が優先される
String a() {
    try {
        throw new Exception();
    } catch (Exception e) {
        return "catch";
    } finally {
        return "finally";
    }
}

System.out.println(a());
// >> finally
```

#### `try`ブロックで宣言した変数は`finally`ブロックからアクセスできない

```java:try ブロックで宣言した変数は finally ブロックからアクセスできない
try (FileInputStream is = new FileInputStream("sample.txt")) {
            
} catch (Exception e) {
    
} finally {
    // コンパイルエラー
    if (is != null) {
    }
}

```

#### リソースのクローズ時の実行順

```java:リソース
class MyResource implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("①close()が実行される");
    }
}
```
```java:リソースのクローズ時の実行順
try (MyResource r = new MyResource()) {
    throw new Exception();
} catch (Exception e) {
    System.out.println("②catchブロックが実行される");
} finally {
    System.out.println("③finallyブロックが実行される");
}

// >> ①close()が実行される
// >> ②catchブロックが実行される
// >> ③finallyブロックが実行される
```

# 参考
・<a href="https://amzn.asia/d/gkx4D5q" target="_blank" rel="noopener noreferrer">徹底攻略Java SE 11 Gold問題集[1Z0-816]対応</a>