インスタンスとメソッド（Java Silver勉強）

# 最初に
この記事は、以下の書籍を通じてJava silverの合格に向けて自分が学んだ内容を体系的にアウトプットする記事である。（目指せ年始合格！）
[徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=asc_df_4295007625/?tag=jpgo-22&linkCode=df0&hvadid=342700130622&hvpos=&hvnetw=g&hvrand=9715255718806805548&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009303&hvtargid=pla-830348236008&psc=1&mcid=e12ce628cc5a33b29a77da3a85a6cdf0&th=1&psc=1)


# 勉強記録

## インスタンスとメソッド

### ガベージコレクション

- 定義
    - プログラムの処理は、メモリの容量を使用する
    - メモリを有効に使うために、利用されないインスタンスを削除し、空きスペースを作る必要がある
    - C言語などでは、プログラムに記述する必要があった
    - しかしjavaでは、JVMの一つの機能であるガベージコレクタが行う
    - これをガベージコレクションと言う
- 補足
    - Systemクラスには、gcメソッドというガベージコレクションを促すメソッドがある（促すだけで実行の保証はない）
    - ガベージコレクションの対象は、どこからも参照されなくなったインスタンス。変数にnullを代入するタイミングで参照が外れる。

### プログラムの実行順序

1. コーディングする
2. 補助記憶装置（電源を切っても消えない不揮発性メモリ）に保存する
3. 主記憶装置（メインメモリ）にプログラムが読み込まれる
    1. コンパイル（機械語に変換）
    2. ロード（読み込み）
4. CPUによって、メインメモリに読み込んだプログラムを処理実行する

https://tech-begin.com/computer-basic/structure/about-program-execution-flow/

### staticなフィールドへのアクセス

- プログラムは、メインメモリに読み込まれる際に、「static領域」「スタック領域」「ヒープ領域」に分けて管理される。
- static領域には、static修飾子がついたメソッドや変数が保存される
- この仕組みのために、staticなフィールドは、インスタンスを作らなくても使える
- また、staticな変数は、インスタンスの値が格納されるヒープ領域とは別のstatic領域に格納されるため、インスタンスを生成しても参照する変数は同じ変数となる

https://ict-skillup.com/java/1630/#toc4

### 実行されないコード

- 実行されないことが明白なコードは、コンパイルエラーとなる
    
    ```clike
    int sample(int num){
    	return num;
    	System.out.println(num); // 実行されないため、コンパイルエラー
    }
    ```
    

### オーバーロード

- オーバーロードとは
    - 同名のメソッドを、**引数を変える**ことにより複数宣言できる機能のこと。
    - 戻り値の型や、メソッド修飾子が異なるのはオーバーロードではない。
- JVMは、実行するメソッドを読み込みとき、メソッド名＋引数のセットで見分ける
- JVMが呼び出すメソッドを判断できない場合、コンパイルエラーとなる
    - 例
    
    ```clike
    public class Main{
    	public static void main(String[] args){
    		Main m = new Main();
    		System.out.println(m.plus(2,4));
    	}
    
    	private double plus(int a, double b){
    	return a + b;	
    	}
    
    	private double plus(double a, int b){
    	return a + b;	
    	}	
    }
    ```
    
    - ちなみに、以下はコンパイルエラーとならない
    
    ```clike
    public class Main{
    	public static void main(String[] args){
    		Main m = new Main();
    		System.out.println(m.plus(2,4));
    	}
    
    	private double plus(int a, int b){
    	// こっちが実行される
    	return a + b;	
    	}
    
    	private double plus(double a, int b){
    	return a + b;	
    	}	
    }
    ```
    

### コンストラクタ

- ルール
    - メソッド名をクラス名と同じにする
    - 戻り値型は記述できない
    - newと一緒にしか使えない（**インスタンス生成時以外は呼び出しができない**）
- コンストラクタを記述しない場合
    - デフォルトコンストラクタ（引数なし、処理なし）を使ってインスタンスが生成される
    - デフォルトコンストラクタは、一つもコンストラクタを記述しなかった場合にしか追加されない
- 初期化子
    - 全てのコンストラクタで共通する処理を実行するために使用
    - 初期化子の記述
    
    ```clike
    public class Sample{
    	{
    	// 初期化子で行う処理の記述
    	}
    }
    ```
    
    - コンストラクタの実行前に実行される（逆に、コンストラクタを実行しない場合は、実行されない）
    - static初期化子の場合は、クラスがロードされたタイミングで実行されるため、クラスメソッドやクラス変数が使用される直前に実行される
    
    ```clike
    public class Sample{
    	static int num;
    	static {
    	// static初期化子で行う処理の記述
    	num = 10;
    	}
    }
    ```
    

### thisの2つの用途

1. オーバーロードされた別のコンストラクタを呼び出す
    1. 別のコンストラクタを呼び出すコードは、最初に記述しないといけない（thisの前に処理を記述してはいけない）
2. インスタンスそのものを表す参照を入れる特別な変数として使う


# 感想
- ガベージコレクションは、うまい感じにJVMがメモリの無駄を省いてくれているくらいの認識だったが、その仕組みの理解が少し深まった。
- コンストラクタの理解は、「インスタンス生成時に呼び出されるもの」くらいの理解度だったのが、さまざまなルールなどがあることを理解することができた。
- 普段eclipseを使って開発しているが、eclipseの補完機能のおかげ（せい）であまり理解しないまま記述していることが自分の思っている以上に多いなぁと思った。