Java | 基礎文法:static メソッド

Java Java
スポンサーリンク

Static メソッドの全体像

static メソッドは「クラスに属するメソッド」で、インスタンス(new で作るオブジェクト)を介さずに呼び出せます。数値計算や文字列整形など「個別の状態に依存しない処理」を、クラス名から直接使える形にするのが目的です。オブジェクトのフィールド(this)には触れられないため、「入力(引数)→出力(戻り値)」の純粋な関数として設計するのが基本です。


基本構文と呼び出し方

定義と呼び出しの最小例

public class MathUtil {
    public static int add(int a, int b) {
        return a + b;
    }
}
Java
public class Demo {
    public static void main(String[] args) {
        int s = MathUtil.add(3, 8); // クラス名.メソッド名で直接呼ぶ
        System.out.println(s);      // 11
    }
}
Java

static を付けると「インスタンス不要」で呼べます。メソッドの中で this は使えません(そもそもインスタンスに紐づかないため)。

インスタンスメソッドとの違い(対比)

class Counter {
    private int value;
    public void inc() { value++; }         // インスタンスメソッド(this が使える)
    public int get() { return value; }
    public static int add(int a, int b) {  // static メソッド(状態に触れない)
        return a + b;
    }
}
Java
  • インスタンスメソッドはオブジェクトの状態を操作します。new Counter() から呼びます。
  • static メソッドは状態に触れない計算やユーティリティに使い、Counter.add(...) のように呼びます。

重要ポイントの深掘り:いつ static を使うか

単一責務の純粋処理に最適

「引数だけで結果が決まる」変換・検証・計算は static が最も読みやすく、安全です。テストも簡単で、依存が少ないため再利用性が高まります。

public class Strings {
    public static boolean isAsciiDigit(char ch) {
        return ch >= '0' && ch <= '9';
    }
}
Java

ユーティリティクラスの作り方

ユーティリティを集約する場合は、状態を持たず、すべて static で提供します。インスタンス化を防ぐために private コンストラクタを置くのが定石です。

public final class Util {
    private Util() {} // 生成禁止
    public static String joinWithComma(String... parts) {
        if (parts == null || parts.length == 0) return "";
        StringBuilder sb = new StringBuilder(parts[0]);
        for (int i = 1; i < parts.length; i++) sb.append(", ").append(parts[i]);
        return sb.toString();
    }
}
Java

エントリポイント main も static

public class App {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}
Java

JVM が最初に呼ぶのは public static void main(String[] args)。インスタンス不要で起動できるのが理由です。


重要ポイントの深掘り:static と状態、テスト容易性

static フィールドに依存しない設計

static フィールド(クラス変数)に依存すると、グローバル状態の共有でバグやテストの難しさを招きます。static メソッドは「引数→戻り値」に閉じると、並行実行でも安全です。

public class Price {
    private static double taxRate = 0.1; // 共有状態は注意が必要
    public static int withTax(int price) {
        return (int) Math.round(price * (1 + taxRate));
    }
}
Java

上のような共有状態は「設定変更の影響範囲が広い」ため、必要最小限にし、変更パスを明示します。理想は「税率も引数で受ける」純粋関数です。

public class Price {
    public static int withTax(int price, double taxRate) {
        return (int) Math.round(price * (1 + taxRate));
    }
}
Java

テストがしやすい理由

依存が少ない(this を使わない・外部状態に触れない)ため、static メソッドは単体テストがシンプルです。モックも不要で、単純な入出力の検証に集中できます。


重要ポイントの深掘り:制約とアンチパターン

this・オーバーライド不可

static は this に触れられず、継承しても「オーバーライドの対象にならない」ため、ポリモーフィズムを使った拡張には向きません。振る舞いの差し替えが必要なら、インスタンスメソッド+インターフェイスを選びます。

interface Formatter { String format(String s); }
class Upper implements Formatter { public String format(String s) { return s.toUpperCase(); } }
Java

乱用で設計が硬直化

何でも static にすると、グローバル関数だらけになりオブジェクト指向の恩恵(拡張性・差し替え・状態封装)を失います。「状態に触れない純粋処理」だけ static、それ以外はインスタンスに寄せるのがバランスです。


実用例で身につける

例 1: 検証と変換を static で

public class Validators {
    public static boolean isEmail(String s) {
        return s != null && s.contains("@") && s.indexOf('@') > 0;
    }
    public static String normalizeName(String s) {
        if (s == null) return "";
        return s.trim().toLowerCase();
    }
}
Java

例 2: 数学ユーティリティ

public final class MathX {
    private MathX() {}
    public static int clamp(int v, int min, int max) {
        if (min > max) throw new IllegalArgumentException("min<=max");
        return (v < min) ? min : (v > max) ? max : v;
    }
}
Java

例 3: main から static を組み合わせて呼ぶ

public class App {
    public static void main(String[] args) {
        String raw = (args.length > 0) ? args[0] : "  Java  ";
        String name = Validators.normalizeName(raw);
        boolean ok = Validators.isEmail("a@b");
        System.out.println(name + " / emailOK=" + ok);
    }
}
Java

設計の指針(重要部分のまとめ)

  • static メソッドは「インスタンス不要・状態に触れない純粋処理」に最適。入力→出力を明確化する。
  • ユーティリティは final+private コンストラクタで集約し、グローバル状態(static フィールド)への依存を最小化する。
  • ポリモーフィズムや差し替えが必要な設計には向かない。拡張性が必要ならインスタンスメソッドとインターフェイスへ寄せる。
  • テスト容易性が高いのが利点。副作用を排して、並行実行でも安全な「関数」として設計する。
  • main は static。起動処理は静的メソッドに分離して、読みやすく再利用しやすい構成にする。

タイトルとURLをコピーしました