本記事の目的
Java のコードを書くと必ず目にする static。
とくに public static void main(String[] args) の意味は最初のつまずきポイントですよね。
この記事では、Java の static とは何かを“イメージ”で掴めるように、実例付きで分かりやすく解説します。
static とは?
public static void main(String[] args){
}
static は インスタンスに属さず、クラスそのものに属することを示す修飾子です。
- 変数(フィールド)
- メソッド
- クラス(ネストしたクラス)
に付けることができます。
static の特徴
- インスタンス不要で使える
newでオブジェクトを作らなくても、呼び出せます
クラス名.staticメソッド();
クラス名.static変数;
- 全てのインスタンスで値を共有する
static 変数はクラスでただ1つのみ存在し、複数のインスタンスで共通の値を参照します。 - メモリ上の配置が異なる
静的なメンバーはクラスロード時に“メソッド領域(static領域とも表現される)”にロードされるため、
インスタンス生成より前に存在します。
インスタンス変数はヒープ領域に生成され、インスタンスごとに別々です。
static の「値共有」を実例で理解する
次のTestクラスを例に、static あり と static なしの動きを見てみましょう。
class Test {
static int staticNum = 0;
int num = 0;
}
① static あり(値が共有される)
public class Main {
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
a.staticNum += 1;
System.out.println(a.staticNum); //実行結果:1
b.staticNum += 1;
System.out.println(b.staticNum); //実行結果:2
}
}
a.staticNumと書いていますが、実際は
Test.staticNum にアクセスしているだけです。
そのため、aが変更した値をbも同じように参照します。
② static なし (値は共有されない)
public class Main {
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
a.num += 1;
System.out.println(a.num); //実行結果:1
b.num += 1;
System.out.println(b.num); //実行結果:1
}
}
インスタンス変数のnumは
インスタンスごとに別々に存在するため、値は共有されません。
なぜ、static は値を共有するのか?
この理由はずばり、
メモリ上の配置がインスタンスと異なるためです。
static の場合
クラスロード時に読み込まれ、
メソッド領域(static な領域)に1つだけ存在する
そのため、どのインスタンスからアクセスしても同じ変数を参照します。
インスタンス変数の場合
newされるたびにヒープ領域に新しく作られる
それぞれのインスタンスごとに別々の値を持つ
まとめ
-
staticはクラスに属するメンバーを定義するための修飾子。 - クラスロード時にメソッド領域へ配置されるため、インスタンスを作らずに使用可能。
- static 変数・メソッドは インスタンスごとのものではないため値が共有される。