「static修羅道」Step08:staticからインスタンス変数は見えない

0005_static修羅道-step08 learn

まずは問題を見ろ

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


問題のポイント

  • static メソッドは、インスタンスを介さずに呼び出せる
  • だから、インスタンス変数にはアクセスできない
  • static を付けると、クラス全体の文脈になるという意味
  • メソッドの「目的」と「所属」を、ちゃんと設計しようという回

まず、日本語で考えろ

  • name という「その人だけが持つデータ」を使いたい
  • でも、static にすると「その人」すらいない状態になる
  • オレが「オレ」って言うためには、オレという存在がいないとダメだろ
  • メソッドが「その人の話」をするなら、staticは外さないといけない

コメントを書け

// ユーザーの名前(name)を持つインスタンス変数を定義
// greet() を static で定義 → name にアクセスできずエラー
// static を外してインスタンスメソッドにすることで、name を使えるようにする

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

public class User {
  private String name;

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

  // static をつけるとエラーになる
  // public static void greet() {
  //   System.out.println("Hello, " + name + "!"); // ← コンパイルエラー
  // }

  // static を外すと、this.name にアクセスできる
  public void greet() {
    System.out.println("Hello, " + name + "!");
  }
}
public class Main {
  public static void main(String[] args) {
    User u1 = new User("Alice");
    User u2 = new User("Bob");

    u1.greet(); // Hello, Alice!
    u2.greet(); // Hello, Bob!
  }
}

コードの解説

  • name は「インスタンスの持ち物」=インスタンス変数
  • static メソッドは、クラス単位で呼び出されるため name には触れない
  • この制限は「文法のせい」ではなく、設計上の区別
  • u1.greet() のように、インスタンスを通じて呼ぶことで name にアクセスできる

つまづきやすいポイント

  • static =便利そう、と思って何でもつけてしまう
  • static は「このクラス全体に属する」ので、個体差(インスタンス変数)にはアクセスできない
  • static と非static の違いが、クラス設計の本質につながってくる

// tesh:
// static をつけると、“オレ”という存在がいなくなる。
// そうなると、name にアクセスできないのは当然や。
// 
// オレという存在(インスタンス)があって初めて、
// 「オレの名前は○○や」と言える。
// 
// static メソッドは、**「クラスという抽象存在が話してる」**ようなもんや。
// 名前? そんなもん知らん。クラス全体の話しかできんのや。
// 
// 「オレが名乗る」ってのは、自分という個体が確かにそこに存在してるってことやろ?
// だから greet() を static にしたら破綻する。“誰の”greetかわからんようになる。
// 
// 逆に言えば、「誰のものでもない処理」──
// 状態に依存せん道具や計算や判定は、staticにする価値がある。
// 
// static か、インスタンスか。
// それを決めるのは、便利さや流行や文法じゃない。
// “その処理は誰に属するのか” っていう設計の問いや。
// 
// コードを書く手を止めて、問いかけろ。
// 「このメソッドは“オレの”処理か? それとも“ウチら全体”の処理か?」ってな。

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