static(静的変数/静的メソッド)についての復習

static宣言について復習したのでメモ。static宣言された変数やメソッドはクラス変数、クラス・メソッド(静的変数、静的メソッド)と呼ばれる。
 
staticはインスタンスと対比すると理解しやすい。

インスタンスとメソッド、フィールド

static 修飾子がついていないフィールド(メンバー変数)やメソッドはインスタンス固有のものであり、インスタンス変数、インスタンス・メソッドと呼びます。
インスタンスとはメモリ上に存在する値のことです。

クラス変数/クラス・メソッド

static 修飾子を指定したフィールド(メンバー変数)やメソッドは、クラス固有でオブジェクト間で共有されるものであり、クラス変数、クラス・メソッドと呼びます。また、静的変数、静的メソッドとも呼ばれます。これらはインスタンス化しなくても利用できます。また、インスタンス化しても、実体として用意されるメモリ領域は、そのクラスをインスタンス化して生成した全てのオブジェクト間で共有されるのです。

要約するとstaticはインスタンスを作成しなくても利用できる。staticは唯一、メモリ上に最初から固有で確保されている孤独な変数/メソッドである。staticをインスタンス化した場合でも、生成されたstaticを含むオブジェクトは生成元のオブジェクト固有のものではなく、全てのオブジェクト間で共有される。
つまり、いくらインスタンスを生成したところで、staticな変数/メソッドは常に1つしか存在しないことになる。

staticな変数/メソッドは常に1つしか存在しないので、全てのオブジェクトから共通のコードでアクセスが可能である。
 
以下にJavaでのstaticの記述方法を載せる。

static変数へのアクセス

クラス名.変数名;

staticメソッドへのアクセス

クラス名.メソッド名();

更に以下のようなコードでもstaticな変数/メソッドへのアクセスが可能である。

static変数へのアクセス

オブジェクト名.変数名

staticメソッドへのアクセス

オブジェクト名.メソッド名()

※オブジェクト名とはインスタンスとして生成したオブジェクトの名前を指す。

以上がクラス外からstaticな変数/メソッドを使う時の注意点になる。
ここでクラス内からstaticな変数/メソッドを扱う時の注意点もまとめておく。

static 修飾されたメソッドは、自分のクラス内のものでも、 static でないメソッドは使うことができません。static修飾されていないメソッドや変数は、オブジェクトに固有のものとして取り扱われるのですが、 staticメソッドからは、どのオブジェクトのものか修飾されていないので分からないからです。

上記の文章の通り、staticな変数/メソッドからはstatic修飾子がついていない変数/メソッドは呼び出せない。
逆にstaticなもの同士ならお互いが固有なものとして扱われてるからお互いに呼び出し合うことが出来る。
更に以下のようにstatic初期化子というものもある。

「メソッド名のないstaticメソッド」。
「static{ 実装 }」のように、戻り値の型もメソッド名も引数もないstaticメソッドは、クラスが使用された時に実行される。
明確に呼び出す必要はなく、また、呼び出すこともできない。何らかの形でそのクラスを使用しようとした時に、自動的に呼び出される。
この機能により「そのクラスのどんなメソッドよりも先に呼び出される」ため、「staticメソッド版コンストラクタ」のように機能し、staticフィールドの初期化処理に使用される。

どういう使い方にメリットがあるのか

  1. 全てのクラスで使用できる定数を用意したい場合にstaticな定数を宣言したクラスを作る。staticな変数には共通のコードでアクセスできる。
  2. 全てのクラスから利用できる共通処理を作る場合にstaticなメソッドを実装したクラスを作る。staticなメソッドには共通のコードでアクセスできる。
  3. staticは一つしか存在できないため、一つしか存在できない特性を活かした処理を作ることができる。

参考
Java 入門 | static キーワード
static初期化子とは : JavaA2Z