「static修羅道」Step01:static変数は共有される

0005_static修羅道-step01 learn

まずは問題を見ろ

javadrill.tech で出題された問題を見る(Step01)


問題のポイント

  • static 変数は すべてのインスタンスで共有される
  • インスタンス変数との違いを出力で明示的に確認する
  • 「個別に持つ情報」か「全体で共有する情報」かを設計として意識する

まず、日本語で考えろ

  • ユーザーがログインするたびに、全体でログイン回数を数えたい
  • Alice がログイン → 1回目
  • Bob がログイン → 2回目
  • Alice がもう1回ログイン → 3回目
  • → つまり、「ユーザー個別の情報」ではなく「全体で1つだけの情報」を持ちたい

コメントを書け

// ユーザー名(個別に保持)
// 全体のログイン回数(すべてのUserで共有)
// login() メソッドでログイン処理をし、全体カウントを加算
// "○○ がログインしました(累計ログイン回数: x)" を出力

コメントに従って、コードを書け

public class User {
  private String name;                      // 各ユーザーの名前
  private static int loginCount = 0;        // 全ユーザー共通のログイン回数

  public User(String name) {
    this.name = name;
  }

  public void login() {
    loginCount++;  // クラス全体で共有されているstatic変数を加算
    System.out.println(name + " がログインしました(累計ログイン回数: " + loginCount + ")");
  }
}
public class Main {
  public static void main(String[] args) {
    User u1 = new User("Alice");
    User u2 = new User("Bob");

    u1.login();  // → 1
    u2.login();  // → 2
    u1.login();  // → 3
  }
}

コードの解説

  • name はインスタンス変数:new User(...) するたびに別の値が保持される
  • loginCountstaticすべてのUserインスタンスで共通の1個だけの変数
  • だから、どのインスタンスがログインしても loginCount は加算されていく

つまづきやすいポイント

  • static を「便利な共有変数」だと思っていると、意味が見えない
  • 大事なのは「設計上、この値は全体で1つだけでいいのか?」という視点
  • その視点がないまま使うと、すぐ「全部staticにしちゃう」初心者病にハマる

// tesh:
// オレが言いたいのは、static を使うなってことじゃねぇ。
// 
// 問題は、「とりあえず共有しときゃ楽っしょ」っていうノリで
// 全部 static にしちゃう、あの“初心者病”や。
// 
// static ってのは、全体にとって “たった1つしかない値” を置く場所。
// つまり、それを変えるってことは──
// 他のすべてのオブジェクトの世界を変えてしまうってことでもある。
// 
// 「1人のログインが、全体のログイン回数を動かす」
// 今回はそれで正解。でも、逆に言えば、
// たった1行で全員に影響するコードを書いてるってこと、
// ちゃんとわかって使ってんのか?
// 
// わかって使ってんなら構わねぇ。
// わかってないのに「staticつけときゃアクセス楽だし〜」で突っ走ると、
// オマエのアプリはすぐ地雷原になる。
// 
// 静かに全体に影響する、それが static の怖さだ。
// 
// 書け。まずは書け。構造をつかめ。
// そして、「共有する覚悟」を持って static を使え。

static修羅道(ステップ一覧)へ戻る