staticメンバーを理解する

staticメンバーは各インスタンスではなくクラスに属します。共有カウンタや補助計算を例に、インスタンスメンバーとの格納場所・呼出し方・利用できる名前の違いを理解します。

この単元で学ぶこと

  • staticフィールドとインスタンスフィールドを区別する
  • staticメソッドからアクセス可能な対象を判定する
  • クラス初期化と実体生成の回数を追う

本文解説

クラスに属するフィールド class Counter { static int total; }のtotalはクラス変数です。Counter.total=3;のようにクラス名でアクセスできます。Counterをnewしていなくても使えます。インスタンスフィールドは実体を指定する必要がある点と異なります。

複数実体からの共有 Counter a=new Counter(),b=new Counter();の後にa.total=2;b.total=5;と書けば同じ共有フィールドを更新し、Counter.totalは5です。文法上変数経由でもアクセスできますが、クラス名で書くほうが共有性を誤解しにくくなります。

個別値との対比 static int total;int local;を持つクラスでadd(){total++;local++;}をaへ二回、bへ一回呼ぶとtotalは3、a.localは2、b.localは1です。共有と個別の二つの格納場所を図で追います。

staticメソッド static int twice(int x){return x*2;}はCounter.twice(3)で呼べます。特定の実体を使わない計算をまとめられます。mainもstaticで、起動のためにMainを自分でnewしてから呼ぶ必要はありません。

非staticへ直接アクセスできない static int read(){return local;}はどの実体のlocalか決まらず不正です。read(Counter c){return c.local;}なら明示した実体を使えるため合法です。staticはオブジェクトを扱えないという意味ではありません。

インスタンス側からstaticを使う インスタンスメソッドは共有フィールドtotalやstaticメソッドを使えます。同じクラス内では単純名でも参照できますが、教材では共有性がわかるクラス名表記も使います。this.totalという書き方をしても個別フィールドには変わりません。

初期化はnewごとでない static int total=4;はクラス初期化で設定されます。その後total=9にし、Counterをnewしても4へ戻りません。インスタンスフィールド初期化子は各実体ごとに実行されるため、どちらの宣言かで回数が異なります。

static final定数 static final int LIMIT=10;はクラス名で共有し再代入しない値を表します。finalなしのstaticは更新可能です。staticが付いているだけで定数になるわけではありません。配列参照等をfinalにしても要素の可変性とは別です。

図解

共有値と個別値
クラス名で共有値を扱うと、インスタンス変数との違いが明確になる。

重要ポイント

  • staticフィールドは同じ実行内のそのクラスで共有する。
  • クラス名.メンバー名でアクセスできる。
  • staticメソッドにはthisがない。
  • インスタンスを指定すればstaticメソッドからもその状態を使える。

間違えやすい点

  • newの回数だけstaticフィールドを作ると思わない。
  • staticメソッドから非staticメンバーを無条件に呼べると思わない。
  • 変数名経由のstaticアクセスをインスタンス状態と混同しない。

用語解説

クラス変数
staticフィールド。各実体ではなくクラスに属する変数。
クラスメソッド
staticメソッド。特定の受け手を必要としないメソッド。
クラス初期化
staticフィールド初期化子やstatic初期化ブロック等を実行する処理。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。