staticをざっくり一言でいうと
フィールドやメソッドを、クラス間で共用できる魔法の修飾子!
9/3追記 下記のように表現するのが一般的とのことです!
フィールド → クラス変数
メソッド → クラスメソッド
そのため、以下の記事内では準拠する形で記述しております。
staticにできるもの
- クラス変数
- クラスメソッド
クラス変数やクラスメソッドをクラス間で共用や上書きができると便利なときもありますよね。
しかし、不意な変更をしてしまう可能性もあるので注意しましょう。
ざっくり説明
まず、通常のクラス変数やクラスメソッドの場合、クラス間で共用するには
- クラス内でクラス変数やクラスメソッドを定義
- 別のクラスで、使用したいクラス変数やクラスメソッドが記載してあるクラスのインスタンスを生成
- インスタンスを経由してクラス変数やクラスメソッドにアクセスする
このような手順となります。
しかし、staticの場合はこれが簡略化されます。
- クラス内でクラス変数やクラスメソッドをstaticを付けて定義
- そのままクラス変数やクラスメソッドを利用できる!
説明
なぜインスタンスを作らなくても使用できるのかについて見ていきましょう。
プログラムの動き
Aクラス(メイン)とBクラス、Cクラスを使用するプログラムを例に考えます。
それぞれのクラスの記載内容は以下となります。
-
Aクラス
- メインクラスメソッド
- Bクラスのインスタンス生成
- Bクラスのクラス変数とクラスメソッドを使用(このとき、上で作ったBクラスのインスタンスを使用している)
- Cクラスのstaticクラス変数とstaticクラスメソッドを使用
-
Bクラス
- クラス変数とクラスメソッドの定義
-
Cクラス
- staticクラス変数とstaticクラスメソッドの定義
このプログラムがコンパイル、実行されたときの動きは下記のようになります。
- 各クラスが読み込まれる
- Aクラス実行
- Aクラスの記載順に、まずはBクラスのインスタンスが生成される
- Aクラスに記載されている、Bクラスのクラスメソッドが読み込まれ、処理がBクラスに移る
- Bクラスの内容が上から順に読み込まれ、実行される。処理が全て終わったら、Aクラスに戻る
- Aクラスに記載されている、Cクラスのクラスメソッドが読み込まれ、処理がCクラスに移る
- Cクラスの内容が上から順に読み込まれ、実行される。処理が全て終わったら、Aクラスに戻る
- 全ての読み込みが完了し、プログラムが終了する
注目していただきたいのは、Bクラスのクラス変数やクラスメソッドと、Cクラスのstaticなクラス変数やクラスメソッドは、メモリ空間上の別の場所に配置されているということです。
手順1「各クラスが読み込まれる」ときに、staticなクラス変数やクラスメソッドは専用のstatic領域に配置されます。
一方、通常のクラス変数やクラスメソッドは、メモリ空間の各インスタンス内に個別に配置されます。
そのため、通常のクラス変数やクラスメソッドは
- インスタンスを生成し、生成したインスタンス経由で使用する
- 各インスタンス内で個別に作られるため、同名であっても異なる値を持つ
というわけなんですね。
そしてstaticなクラス変数やクラスメソッドの場合は
- メモリ空間上の専用領域に配置される
- インスタンス内にあるわけではないので、インスタンスを生成する必要がない
- 専用空間に配置されるので、同名のstaticなものを複数定義できない
- 参照先が一つなので、どのクラスからアクセスしても同一の値を返す
となるわけです。
staticの真意
冒頭でお伝えした、『staticとはクラス変数やメッソドを、クラス間で共用できる魔法の修飾子!』というのは半分当たっていて、半分外れています。
プログラムを動かしたときに、複数のクラスから呼び出されるstaticクラス変数やstaticクラスメソッドが呼び出す度に値や実行内容が変わってしまっては大変ですよね。
実は、static(意味:静的な、不活の、動きのない)の真意は、『参照先が一つなので、どのクラスからアクセスしても同一の値を返す = 変わらないものを定義する時に利用する』です。
例えばファイルパスや変更予定のないクラスメソッド、内容が変わってしまっては困るクラスメソッドなどへの使用が主となります。
staticの注意点
staticクラスメソッドから、通常の変数やクラスメソッドへアクセスすることはできません!
staticからはstaticなものへのみ、アクセスできます。
まとめ
staticとは不変に保ちたいクラス変数やクラスメソッドにつける修飾子であり、staticなクラス変数やクラスメソッドは、インスタンスを生成しなくても使用することができます。
後書き
私自身、Javaを勉強している途中ですので、記事内の表現について誤った部分のある可能性があります。
概略は間違っていないと思いますので、初心者の方の理解促進の一助となっていれば幸いです。
また、冒頭と終わりで真逆に近いような内容を伝えていることについては、ヒングロマクソン族でいうマダオみたいな感じで受け取っていただければと……。