Javaのstatic修飾子：クラス変数（static変数）、クラスメソッド（staticメソッド）

## static修飾子とは
static修飾子は変数（フィールド）やメソッドにつける修飾子でクラスのオブジェクト（インスタンス）を生成しなくても呼び出す事が出来る様になる。
static修飾子をつけた変数は「クラス名.変数名」、static修飾子をつけたメソッドは「クラス名.メソッド名」の様に「クラス名.」の後に記述する事が出来るため、それぞれを**クラス変数（static変数）**、**クラスメソッド（staticメソッド）** と呼ぶ。
```:サンプルコード
 public class Sample{
    //クラス変数（static変数）
    public static int num = 0;
    //クラスメソッド（staticメソッド）
    public static void sampleMethod{
             :
  }
}
```

## クラス変数（static変数）とは
staticキーワード（修飾子）を付けて宣言される変数であり、すべてのオブジェクト（インスタンス）で共有される共通の情報となる。あるオブジェクトからクラス変数の値を変更すると、その他のすべてのオブジェクトに影響が及ぶため、オブジェクト全体に共通する情報を扱いたい場合に使用する。

static修飾子がついていない変数は**インスタンス変数**と呼ぶ。

**クラス変数とインスタンス変数の違いは、staticとして宣言するかしないか。**
・インスタンス変数はクラスのオブジェクト（インスタンス）を生成したタイミングで作られる変数でクラスのオブジェクト（インスタンス）ごとに管理されている（オブジェクトごとに変数が作られる）。

```:クラス変数の宣言方法
アクセス修飾子 static データ型 変数名();
```
＊アクセス修飾子は必要な時に記述
```:クラス変数へのアクセス方法
クラス名.変数名

//インスタンス変数の場合
インスタンス名.変数名
```

## クラスメソッド(staticメソッド)とは
Javaにおいて通常のメソッドは、クラスをインスタンス化してから使用するがstatic修飾子を付与したクラスメソッドは、クラスのインスタンス化なしに直接呼び出して使用できる。
クラスメソッドは、クラスに紐付けられたメソッドであり、クラス全体に関連する処理を定義する。
static修飾子がついていないメソッドである**インスタンスメソッド**は名前の通り、インスタンスに紐付けられたメソッドであるため、クラスからインスタンスを生成しないと利用することが出来ない。

```:クラスメソッドの定義方法
アクセス修飾子 static 戻り値 メソッド名(引数) {
  // 処理内容
}
```
```:クラスメソッドの呼び出し方
クラス名.メソッド名();
//例文
 Student4 stu1 = new Student4("菅原");
    Student4.display();

//インスタンスメソッドの場合
インスタンス名.メソッド名();
//例文
 Student4 stu1 = new Student4("菅原");
    stu1.display();
```
＊アクセス修飾子は必要な時に記述

### クラスメソッド(staticメソッド)の使い方
クラスメソッド(staticメソッド)の主な使い方はインスタンス（オブジェクト）の状態に依存しない処理をさせる事。（これを**ユーティリティメソッド** とも呼び、決まり切った処理に用いられる）

### static修飾子の使いどころ
①全部のインスタンスから共通して変数やメソッドを作りたい時
②クラスに関連する便利なメソッド、使いたいメソッドをまとめたい時

## 例文

### static修飾子をつける前にコード
```:実行用クラス
class StuSample4{
  public static void main(String[] args){
    Student4 stu1 = new Student4("菅原");
    stu1.display();

    Student4 stu2 = new Student4("田仲");
    stu.display();
  }
}
```
```:設計図クラス
class Student4{
  String name;
  int counter = 0;

  Student4(String n){
    name = n;
    counter++;
    System.out.println(name + "さんをインスタンス化しました");
  }
  void display(){
    System.out.println(counter + "人です");
  }
}
```
```:出力結果
菅原さんをインスタンス化しました
1人です
田仲さんをインスタンス化しました
1人です
```

### static修飾子をつけた場合のコード
```:実行用クラス
class StuSample4{
  public static void main(String[] args){
    Student4.display();　← 追記

    Student4 stu1 = new Student4("菅原");
    Student4.display();

    Student4 stu2 = new Student4("田仲");
    Student4.display();
  }
}
```
```:設計図クラス
class Student4{
  String name;
  static int counter = 0;

  Student4(String n){
    name = n;
    counter++;
    System.out.println(name + "さんをインスタンス化しました");
  }
  static void display(){
    System.out.println(counter + "人です");
  }
}
```
```:出力結果
0人です
菅原さんをインスタンス化しました
1人です
田仲さんをインスタンス化しました
2人です
```
static修飾子をつける前にコードでは設計図クラスで4行目で変数counterの値に0を定義して７行目でインクリメントされる度に値が加算される様にしている。変数counterの値は保持されたままなので（下の写真はイメージ）「1人です」という出力が2回されている
![スクリーンショット 2022-11-03 15.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/29524e49-dbac-8d56-e0c8-43577fd79053.png)


static修飾子をつけた場合のコードでは変数counterにstatic修飾子をつけることでクラス変数にしている。これにより変数counterは静的な変数（1つのみ存在する変数）になったので「一つのメモリに入った実体」となる。
同様に１０行目のdisplayメソッドもstatic修飾子をつけることでクラスメソッドにしたのでインスタンス（オブジェクト）に依存しない状態になった。

![スクリーンショット 2022-11-06 10.46.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2785154/4353471f-c61c-88fd-4ead-471a946b5150.png)



実行用クラスではstatic修飾子をつける前にコードの例文に４、７行目のインスタンスメソッドをクラスメソッドに変更している。

変数counterはクラス変数になったので0という値が入った「一つの実体」となっているのでstatic修飾子をつけた後の実行用クラスに追記されたStudent4.display();で呼び出されて「0人です」という出力結果を出すことが出来る。
「一つのメモリに入った実体」の状態なのでcounter++;で値が加算されていき「1人です」「2人です」と出力される。

## 参考記事
https://www.youtube.com/watch?v=P9CVQ6IuquM

https://medium-company.com/java-static/