104 「static修羅道」 Step01 解答例


User.java

public class User {
  // ユーザー名(これはインスタンスごとに異なるので、非staticで定義)
  private String name;

  // 全ユーザーで共有するログイン回数(staticを使ってクラスに属させる)
  private static int loginCount = 0;

  // コンストラクタでユーザー名を設定する
  public User(String name) {
    this.name = name;
  }

  // ユーザーがログインしたときに呼ばれるメソッド
  public void login() {
    // クラス全体で共有されている loginCount を1つ増やす
    loginCount++;

    // ユーザー名と、全体での累計ログイン回数を出力する
    System.out.println(name + " がログインしました(累計ログイン回数: " + loginCount + ")");
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    // ユーザーを2人作成
    User u1 = new User("Alice");
    User u2 = new User("Bob");

    // 各ユーザーがログインする
    u1.login();  // 1回目のログイン
    u2.login();  // 2回目のログイン
    u1.login();  // 3回目のログイン
  }
}

出力結果

Alice がログインしました(累計ログイン回数: 1)
Bob がログインしました(累計ログイン回数: 2)
Alice がログインしました(累計ログイン回数: 3)

解説

この問題では、static 変数がインスタンスに属さず、クラス全体で共有されるという性質を体験します。

🔸 staticでない変数(name)

javaCopyEditprivate String name;

これは User の各インスタンスが持つ「自分専用の値」です。
new するたびに別々の name が保持されます。


🔹 staticな変数(loginCount)

javaCopyEditprivate static int loginCount = 0;

この変数は クラス全体で1つだけ存在する共有のカウンタです。
複数のインスタンスがこの変数を使い回します。どのインスタンスから呼び出しても値は共通で、書き換えた内容が全体に反映されます。

つまり:

  • u1.login() で 1 → 2
  • u2.login() で 2 → 3

とカウントアップされるのは、この loginCount がクラスに属しているからです。


なぜ static を使うのか?

このケースでは「ログイン回数を全体で管理したい」という意図があります。
インスタンス(個人)ではなく、全体での状態を保持するなら、static が必要です。

逆に言えば、「この情報は全体で1つだけでいいか?」と考えると、static を使うべきかどうかの判断ができるようになります。


まとめ

  • static 変数は クラスに1つだけ存在する
  • すべてのインスタンスで 共有される
  • 状態や情報を 全体で保持したいときに使う
  • 対して、個別に保持したい情報はインスタンス変数として宣言する

104 ステップアップ問題 「static修羅道」


Just Keep Typing, Baby!では、この「static修羅道」でつまづいた人向けの解説をしています。こちらもぜひ!

// tesh:
// ここ、スルーしても通れる。でも通じなくなるぞ。