/** * ドメイン非依存URL出力フィルタ * javadrill.tech移行時はwp_options.home/siteurlのみ変更すればよい * * データベースには絶対URL(https://minner.asia)を保持し、 * 表示時に現在のドメイン(home_url())に動的変換する */ function javadrill_make_urls_dynamic($content) { if (empty($content)) { return $content; } // データベース内の絶対URLを現在のhome_url()に置換 $old_url = 'https://minner.asia'; $new_url = untrailingslashit(home_url()); // http版も対応(念のため) $content = str_replace($old_url, $new_url, $content); $content = str_replace('http://minner.asia', $new_url, $content); return $content; } // 投稿本文、ウィジェット、タームの説明、抜粋に適用 add_filter('the_content', 'javadrill_make_urls_dynamic', 20); add_filter('widget_text', 'javadrill_make_urls_dynamic', 20); add_filter('term_description', 'javadrill_make_urls_dynamic', 20); add_filter('get_the_excerpt', 'javadrill_make_urls_dynamic', 20); 104「static修羅道」 | Javaドリル https://minner.asia 楽々学べるJavaの問題集 Fri, 05 Sep 2025 01:54:15 +0000 ja hourly 1 https://wordpress.org/?v=6.8.3 https://minner.asia/wp-content/uploads/2023/10/cropped-logo-32x32.png 104「static修羅道」 | Javaドリル https://minner.asia 32 32 104 「static修羅道」 StepFinal 解答例 https://minner.asia/archives/5245 https://minner.asia/archives/5245#respond Wed, 28 May 2025 03:42:36 +0000 http://localhost/?p=5245

Player.java

public class Player {
  // インスタンス変数:プレイヤーの名前
  private String name;

  // インスタンス変数:プレイヤーのスコア
  private int score;

  // クラス変数:全プレイヤーに共通の最高スコア
  private static int highScore = 0;

  // コンストラクタ:名前を初期化、スコアは0のまま
  public Player(String name) {
    this.name = name;
    this.score = 0;
  }

  // スコアを更新し、必要に応じて highScore も更新する
  public void setScore(int newScore) {
    this.score = newScore;

    // 最高スコアを上回っていれば更新
    if (newScore > highScore) {
      highScore = newScore;
    }
  }

  // プレイヤーのスコア情報を出力
  public void display() {
    System.out.println(name + " のスコア: " + score + "(現在の最高スコア: " + highScore + ")");
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    Player p1 = new Player("Alice");
    Player p2 = new Player("Bob");

    p1.setScore(50);
    p1.display(); // Alice のスコア: 50(現在の最高スコア: 50)

    p2.setScore(80);
    p2.display(); // Bob のスコア: 80(現在の最高スコア: 80)

    p1.setScore(100);
    p1.display(); // Alice のスコア: 100(現在の最高スコア: 100)
  }
}

実行結果

Alice のスコア: 50(現在の最高スコア: 50)
Bob のスコア: 80(現在の最高スコア: 80)
Alice のスコア: 100(現在の最高スコア: 100)

解説

この最終ステップでは、「staticと非staticの設計的な使い分け」を統合的に理解します。


score はインスタンス変数(非static)

  • 各プレイヤーが 自分専用のスコア を持っている
  • だから private int score; は非static
  • p1 のスコアと p2 のスコアは完全に独立して存在する

highScore はstatic変数(クラス全体で共有)

  • 「最高スコア」はゲーム全体で1つだけ存在すればいい
  • どのプレイヤーがスコアを更新しても、条件に応じて highScore に反映される

setScore() のロジックに設計の意図を込める

if (newScore > highScore) {
  highScore = newScore;
}
  • この一行が、「全体で共有される記録を管理する」という static の意味と責任を表している
  • static を使うことによって、「設計でコードに意図を刻む」ことができる

まとめ

  • インスタンスごとの情報(name, score)は非staticで持つべき
  • 全体で1つしか存在しない情報(highScore)はstaticで持つべき
  • static を使うかどうかは「値を共有すべきかどうか」で判断する
  • 設計意図をコードに刻む──それがstatic修羅道のゴール

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


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

// tesh:
// 大丈夫。書いたオレも昔つまずいた。だから残してある。

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5245/feed 0
104 「static修羅道」 StepFinal 問題 https://minner.asia/archives/5241 https://minner.asia/archives/5241#respond Wed, 28 May 2025 03:38:48 +0000 http://localhost/?p=5241

問題

あなたは、ゲームに登場するプレイヤーのスコアを管理するクラス Player を設計しようとしています。
このクラスには次の2つの目的があります:

  1. 各プレイヤーが持つ個別のスコアを保持する
  2. 全体での最高スコア(high score)を記録し、共有する

プレイヤーがスコアを更新するたびに、新しいスコアがそれまでの最高スコアを超えていれば、クラス全体の最高スコアも更新されるようにしてください。

以下のような出力になるように実装してください:

Alice のスコア: 50(現在の最高スコア: 50)
Bob のスコア: 80(現在の最高スコア: 80)
Alice のスコア: 100(現在の最高スコア: 100)

要件

  • Player クラスを作成すること
  • インスタンス変数:name, score を定義すること
  • static変数:highScore を定義し、すべてのプレイヤー間で共有すること
  • setScore(int newScore) メソッドで、スコア更新と highScore の自動更新を行うこと
  • display() メソッドで、名前 + スコア + 現在の最高スコア を出力すること
  • 出力には System.out.println を使用すること

テストコード(Main.java)

public class Main {
  public static void main(String[] args) {
    Player p1 = new Player("Alice");
    Player p2 = new Player("Bob");

    p1.setScore(50);
    p1.display();

    p2.setScore(80);
    p2.display();

    p1.setScore(100);
    p1.display();
  }
}

ヒント

  • highScore はすべてのプレイヤーで共有される static 変数
  • setScore() の中で、if (newScore > highScore) で比較・更新
  • display() は name, score, highScore ã‚’1行で表示する

→ 解答例はこちら

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

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5241/feed 0
104 「static修羅道」 Step09 解答例 https://minner.asia/archives/5236 https://minner.asia/archives/5236#respond Wed, 28 May 2025 03:35:49 +0000 http://localhost/?p=5236

Document.java

public class Document {
  // 書類のタイトル(インスタンスごとに異なる)
  private String title;

  // 書類のページ数(インスタンスごとに異なる)
  private int pages;

  // 全書類で共有される「合計ページ数」
  private static int totalPages = 0;

  // コンストラクタ:タイトルとページ数を受け取り、合計ページ数に加算
  public Document(String title, int pages) {
    this.title = title;
    this.pages = pages;

    // クラス全体の合計に加算
    totalPages += pages;
  }

  // 書類情報を出力(インスタンスの情報+クラスの統計情報)
  public void printInfo() {
    System.out.println(title + ": " + pages + "ページ(現在の合計: " + totalPages + ")");
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    Document d1 = new Document("書類A", 5);
    Document d2 = new Document("書類B", 3);
    Document d3 = new Document("書類C", 7);

    d1.printInfo();
    d2.printInfo();
    d3.printInfo();
  }
}

実行結果

書類A: 5ページ(現在の合計: 5)
書類B: 3ページ(現在の合計: 8)
書類C: 7ページ(現在の合計: 15)

解説

「個別の情報」と「全体の統計」を使い分ける

この問題の設計には、以下の2種類の情報が存在します:

  • pages:この書類だけのページ数(インスタンス変数)
  • totalPages:すべての書類の合計ページ数(static変数)

それぞれの性質に合わせて、正しいスコープで変数を設計するのがポイントです。


static変数のふるまい

private static int totalPages = 0;

この変数はクラス全体で1つだけ存在し、new Document(...) するたびにページ数が加算されていきます。

つまり、全体の状態(統計情報)を記録する役割を担っているわけです。


インスタンスの役割とstaticの役割を設計で分離する

  • インスタンス変数:そのオブジェクトだけが持つ情報(ページ数、タイトルなど)
  • static変数:クラス全体で共有する情報(合計、IDカウンタ、設定など)

Javaでは、この「責任の切り分け」が static を設計に活かすポイントです。


まとめ

  • static 変数は「全体で共有される情報」の保持に適している
  • インスタンスごとの情報(title, pages)とは設計上の責務が異なる
  • totalPages のような統計的な情報は、クラス単位で管理するべき

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


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

// tesh:
// あとで調べ直すくらいなら、今、読もうぜ。

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5236/feed 0
104 「static修羅道」 Step09 問題 https://minner.asia/archives/5232 https://minner.asia/archives/5232#respond Wed, 28 May 2025 03:31:37 +0000 http://localhost/?p=5232

問題

あなたは、書類を処理する Document クラスを設計しています。
このクラスでは、次の2つの目的を達成してください:

  1. 各インスタンスが「自分が何ページの書類か」を記録する
  2. すべての書類インスタンスのページ数合計を、クラスで集計する

つまり、インスタンスごとのページ数と、全体での合計ページ数の両方を出力するようにします。

以下のような出力になるようにしてください:

書類A: 5ページ(現在の合計: 5)
書類B: 3ページ(現在の合計: 8)
書類C: 7ページ(現在の合計: 15)

要件

  • Document クラスを作成すること
  • インスタンス変数:title(書類のタイトル), pages(ページ数)を定義すること
  • static変数:totalPages を定義し、すべてのページ数の合計を保持すること
  • コンストラクタで、タイトルとページ数を受け取り、totalPages を加算すること
  • printInfo() メソッドで、各書類のページ数と合計ページ数を出力すること
  • 出力は System.out.println を使用すること

テストコード(Main.java)

public class Main {
  public static void main(String[] args) {
    Document d1 = new Document("書類A", 5);
    Document d2 = new Document("書類B", 3);
    Document d3 = new Document("書類C", 7);

    d1.printInfo();
    d2.printInfo();
    d3.printInfo();
  }
}

ヒント

  • totalPages はクラス全体で共有される static 変数
  • totalPages += pages; のように、コンストラクタ内で加算する
  • printInfo() の中で static 変数とインスタンス変数を組み合わせて出力する

→ 解答例はこちら

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

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5232/feed 0
104 「static修羅道」 Step08 解答例 https://minner.asia/archives/5228 https://minner.asia/archives/5228#respond Wed, 28 May 2025 02:23:53 +0000 http://localhost/?p=5228

間違ったコード(staticメソッドからインスタンス変数へアクセス)

public class User {
  private String name;

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

  // ※ staticをつけてしまうと、nameが使えずコンパイルエラーになる
  public static void greet() {
    System.out.println("Hello, " + name + "!"); // ← name に赤線(エラー)
  }
}

このコードは コンパイルエラー になります。

non-static variable name cannot be referenced from a static context

正しいコード(staticを外す)

public class User {
  private String name;

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

  // 正しいバージョン:インスタンスメソッド
  public void greet() {
    System.out.println("Hello, " + name + "!");
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    User u1 = new User("Alice");
    User u2 = new User("Bob");

    u1.greet();
    u2.greet();
  }
}

実行結果

Hello, Alice!
Hello, Bob!

解説

staticメソッドとは?

  • staticメソッドは クラスに属しており、インスタンスを持たない
  • new しなくても呼び出せる(例:Math.abs())

だからこそ──

public static void greet() {
  System.out.println("Hello, " + name + "!");
}

このように書いても、name の「中身」が存在しない。
staticメソッドには「誰の name か」がわからないからです。


なぜエラーになるのか?

name は以下のように、インスタンスに属するフィールド(非static)です。

private String name;

これを使うには、「そのインスタンス」が必要です。
でも staticメソッドはインスタンスを前提にしていないため、そもそも name を持っていないのです。


解決方法は?

static を外して、インスタンスメソッド(非static)として定義すること。

public void greet() {
  System.out.println("Hello, " + name + "!");
}

これで this.name が使えるようになります。


まとめ

  • staticメソッドは インスタンスなしで使う設計
  • インスタンス変数(非static)は 各オブジェクトが持つ個別の情報
  • staticメソッドからは インスタンス変数にアクセスできない
  • もしアクセスしたいなら、インスタンスメソッドとして書く

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


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

// tesh:
// よくわからんまま進めても、どっかでツケが来る。

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5228/feed 0
104 「static修羅道」 Step08 問題 https://minner.asia/archives/5223 https://minner.asia/archives/5223#respond Wed, 28 May 2025 02:18:12 +0000 http://localhost/?p=5223

問題

あなたは、User クラスに greet() というメソッドを定義しようとしています。
このメソッドでは、ユーザーの名前(name)を使って挨拶メッセージを出力したいと考えています。

しかし、うっかりこの greet() メソッドを static として定義してしまうと、
name というインスタンス変数にアクセスできずエラーになることに気づきます。

この問題では、static メソッドと インスタンス変数の関係性を確認し、
エラーになる理由と正しい設計を体験してください。


出力のイメージ(正しく書けた場合)

Hello, Alice!
Hello, Bob!

要件

  • User クラスを作成し、インスタンス変数 name を定義すること
  • greet() メソッドで System.out.println("Hello, " + name + "!"); を出力すること
  • 最初に greet() ã‚’ static で書き、コンパイルエラーになることを確認する
  • エラーの原因を理解し、staticを外して修正したバージョンを作成すること

テストコード(Main.java)

public class Main {
  public static void main(String[] args) {
    User u1 = new User("Alice");
    User u2 = new User("Bob");

    u1.greet();
    u2.greet();
  }
}

ヒント

  • staticメソッドは インスタンスがなくても呼べるが、
    インスタンス変数は インスタンスに属するため static からは見えない
  • static を外してメソッドをインスタンスメソッドにすれば name を使えるようになる

→ 解答例はこちら

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

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5223/feed 0
104 「static修羅道」 Step07 解答例 https://minner.asia/archives/5219 https://minner.asia/archives/5219#respond Wed, 28 May 2025 02:15:16 +0000 http://localhost/?p=5219

User.java

public class User {
  // クラス全体で共有する「次に割り当てるID」
  private static int nextId = 1;

  // このインスタンスに割り当てられたID(個別)
  private int id;

  // ユーザーの名前(個別)
  private String name;

  // コンストラクタ:Userを生成するたびにIDを自動で付ける
  public User(String name) {
    this.id = nextId;  // 今のnextIdを割り当て
    nextId++;          // 次のインスタンス用に+1しておく
    this.name = name;
  }

  // ユーザー情報を出力
  public void printInfo() {
    System.out.println("[ID: " + id + "] 名前: " + name);
  }
}

Main.java

public class Main {
  public static void main(String[] args) {
    User u1 = new User("Alice");
    User u2 = new User("Bob");
    User u3 = new User("Carol");

    u1.printInfo();
    u2.printInfo();
    u3.printInfo();
  }
}

実行結果

[ID: 1] 名前: Alice
[ID: 2] 名前: Bob
[ID: 3] 名前: Carol

解説

この問題では、インスタンスごとに一意なIDを自動付与する方法として
static 変数をカウンタとして使うテクニックを学びました。


staticな nextId とは?

private static int nextId = 1;
  • すべての User インスタンスで 共有されるカウンタ
  • 初期値を 1 にしておき、インスタンスが作られるたびに1つずつ増やす
  • id = nextId; nextId++; によって、一意なIDを順番に割り振ることができる

なぜ id は非staticなのか?

private int id;
  • id はそのインスタンス専用の情報
  • static にしてしまうと、全インスタンスが同じ値を持ってしまう
  • 各インスタンスが 自分だけのID を持つためには、非staticである必要がある

現場でよく使われる設計

このような「ID連番割り振り」は、実際の開発現場でも非常によく使われます。

例:

  • ユーザーID
  • 注文番号
  • セッション番号

いずれも「一意な番号を自動でふる」ために static 変数を活用します。


まとめ

  • static 変数は インスタンス間で共有するカウンタとして使える
  • コンストラクタ内で id = nextId++ とすることで、一意なIDを割り当てられる
  • static と非static の「役割の違い」を、設計として使い分けることが重要

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


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

// tesh:
// 似た問題でまた詰まる未来、見えてるなら止めよう。

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5219/feed 0
104 「static修羅道」 Step07 問題 https://minner.asia/archives/5215 https://minner.asia/archives/5215#respond Wed, 28 May 2025 02:10:44 +0000 http://localhost/?p=5215

問題

あなたは、User クラスのインスタンスを生成するたびに、
一意の連番ID(ユーザーID) を自動的に割り振る仕組みを作ろうとしています。

IDは 1, 2, 3… と順に増加し、すべての User インスタンスで重複せずに一意になる必要があります。

このために、static 変数を使って、インスタンス生成時に自動的にIDが割り振られるようにしてください。

以下のような出力になるように実装してください:

[ID: 1] 名前: Alice
[ID: 2] 名前: Bob
[ID: 3] 名前: Carol

要件

  • User クラスを作成すること
  • static な nextId 変数(int型)を用意し、IDの連番管理を行うこと
  • 各インスタンスは id(int型)と name(String型)を保持すること
  • コンストラクタで id を自動的に割り当てること(nextId++)
  • printInfo() メソッドで [ID: x] 名前: y の形式で出力すること
  • 出力には System.out.println を使用すること

テストコード(Main.java)

public class Main {
  public static void main(String[] args) {
    User u1 = new User("Alice");
    User u2 = new User("Bob");
    User u3 = new User("Carol");

    u1.printInfo();
    u2.printInfo();
    u3.printInfo();
  }
}

ヒント

  • nextId はすべてのインスタンスで共有する必要があるので static
  • id は個々のインスタンス専用なので非static
  • コンストラクタの中で id = nextId++ とすると一意の番号を割り振れる

→ 解答例はこちら

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

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5215/feed 0
104 「static修羅道」 Step06 解答例 https://minner.asia/archives/5210 https://minner.asia/archives/5210#respond Wed, 28 May 2025 02:07:44 +0000 http://localhost/?p=5210

AppConfig.java

import java.time.LocalDateTime;

public class AppConfig {

  // アプリのバージョン(クラス共通で1つ)
  public static String VERSION;

  // デバッグモード(true: ON, false: OFF)
  public static boolean DEBUG_MODE;

  // 読み込まれた時刻
  public static LocalDateTime LOADED_AT;

  // static初期化ブロック:クラスが最初に読み込まれた時に1度だけ実行される
  static {
    VERSION = "1.0.0";
    DEBUG_MODE = true;
    LOADED_AT = LocalDateTime.now(); // 実行時の時刻を記録
  }

  // 設定情報を出力するメソッド(staticなのでインスタンス化不要)
  public static void printConfig() {
    System.out.println("App Config:");
    System.out.println("VERSION: " + VERSION);
    System.out.println("DEBUG_MODE: " + DEBUG_MODE);
    System.out.println("LOADED_AT: " + LOADED_AT);
  }

  // インスタンス化は不要なのでコンストラクタは定義しない
}

Main.java

public class Main {
  public static void main(String[] args) {
    // アプリ設定情報を出力
    AppConfig.printConfig();
  }
}

実行結果(例)

App Config:
VERSION: 1.0.0
DEBUG_MODE: true
LOADED_AT: 2025-05-26T10:15:30.123456

(※ 実行タイミングによって LOADED_AT の値は変わります)


解説

この問題では、static初期化ブロックの特徴と用途を理解します。


static初期化ブロックとは?

static {
  // 初期化処理
}

これは クラスが最初に読み込まれた瞬間に1度だけ実行される 特別なブロックです。

  • コンストラクタと違い、インスタンスを作らなくても実行される
  • 初期値に時間や外部情報を含めるときに便利
  • static変数の複雑な初期化処理 に向いている

static変数と初期化の関係

public static String VERSION;

このように定義された static 変数は、**クラス全体で共有される「設定項目」**のようなものです。

たとえば:

  • VERSION: 固定値(定数でもいい)
  • DEBUG_MODE: 動作モードの切り替えに使える
  • LOADED_AT: 起動時刻など、1回だけ決定するべき値

こういった値を「まとめて」初期化できるのが staticブロックの強みです。


なぜコンストラクタではなく staticブロックなのか?

  • コンストラクタは インスタンスごとに呼ばれる
  • AppConfig のような設定クラスは newしない設計なので、コンストラクタが実行されない
  • それでも「一度だけの初期化」は必要
    → そこで static初期化ブロックを使う

まとめ

  • static {} は クラスが最初にロードされた瞬間に実行される1回限りの処理
  • static 変数の複雑な初期化や外部依存の初期化に適している
  • この仕組みを使えば、newしないクラスでも一度きりの準備ができる

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


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

// tesh:
// ここ、分かると一気にラクになる。マジで。

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5210/feed 0
104 「static修羅道」 Step06 問題 https://minner.asia/archives/5206 https://minner.asia/archives/5206#respond Wed, 28 May 2025 02:03:02 +0000 http://localhost/?p=5206

問題

あなたは、アプリケーションの起動時に一度だけ読み込まれる 設定情報を管理するクラスを作ろうとしています。

このクラスでは、以下のような static変数 を用意し、それらを static初期化ブロックで初期化してください。

  • VERSION:アプリケーションのバージョン(例: "1.0.0")
  • DEBUG_MODE:デバッグモードのON/OFF(例: true)
  • LOADED_AT:設定が読み込まれた時刻(LocalDateTime.now() で取得)

この設定情報を表示する printConfig() という staticメソッド を定義し、
mainメソッドから1回だけ呼び出して、設定情報を出力してください。

出力例:

App Config:
VERSION: 1.0.0
DEBUG_MODE: true
LOADED_AT: 2025-05-26T10:15:30.123456

要件

  • AppConfig クラスを作成すること
  • VERSION, DEBUG_MODE, LOADED_AT はすべて static 変数として定義すること
  • 値の初期化はすべて static初期化ブロック の中で行うこと
  • printConfig() メソッドは static にし、mainメソッドから呼び出すこと
  • 出力は System.out.println を使用すること

テストコード(Main.java)

public class Main {
  public static void main(String[] args) {
    AppConfig.printConfig();
  }
}

ヒント

  • static初期化ブロックは static { ... } の形式で書く
  • LocalDateTime.now() を使うには import java.time.LocalDateTime; が必要
  • 初期化はコンストラクタではなく、クラスが最初に読み込まれたときに1回だけ行われる

→ 解答例はこちら

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

🎯 実習で理解を深めよう

この内容についてJavaDrillで実際に手を動かして学習できます

]]>
https://minner.asia/archives/5206/feed 0