2.

Java staticメソッドの使い方|インスタンス不要・ユーティリティクラス

編集
この記事の要点
  • static メソッド(クラスメソッド)はインスタンス化せずクラス名から直接呼べる
  • 呼び出し: クラス名.メソッド名(...)Math.abs() / Integer.parseInt() などが典型
  • static メソッド内ではインスタンス変数 / インスタンスメソッドを直接使えない(this も使えない)
  • オーバーライドできない(サブクラスでの再定義はメソッドの隠蔽になる)
  • 入出力が引数だけで決まる純粋関数的なユーティリティに向く。状態を持つ処理は通常のメソッドへ

static メソッドとは

static メソッド(クラスメソッド)は、static 修飾子を付けて宣言されたメソッドです。クラスをインスタンス化せず、クラス名から直接呼び出せるのが特徴です。

基本構文

public class MathUtil {
    // static メソッド
    public static int add(int a, int b) {
        return a + b;
    }
}

// 呼び出し
int s = MathUtil.add(1, 2);   // インスタンス化不要

インスタンスメソッドとの違い

項目static メソッドインスタンスメソッド
呼び出しクラス名.メソッド()インスタンス.メソッド()
this使えない使える
インスタンス変数アクセス不可(直接は)
オーバーライド不可(隠蔽になる)
メモリクラスロード時に 1 つインスタンスごと
テスト状態を持たないと容易モック注入で柔軟

標準ライブラリの static メソッド例

// 数値ユーティリティ
double r = Math.sqrt(2.0);
int    a = Math.abs(-5);

// 文字列 ↔ 数値
int n = Integer.parseInt("42");
String s = String.valueOf(123);

// 配列ユーティリティ
java.util.Arrays.sort(arr);
java.util.List<Integer> list = java.util.Arrays.asList(1, 2, 3);

// コレクション
java.util.Collections.sort(list);

static の制約

static メソッド内では、インスタンス変数や非 static のメソッドを直接使えません。下記はコンパイルエラーになります。

public class Sample {
    int x = 10;                 // インスタンス変数
    void show() { ... }         // インスタンスメソッド

    public static void main(String[] args) {
        System.out.println(x);  // ❌ エラー
        show();                 // ❌ エラー
        Sample s = new Sample();
        System.out.println(s.x); // ✅ インスタンス経由ならOK
        s.show();                // ✅
    }
}

使い分けの目安

シーン推奨理由
引数のみで結果が決まる計算static純粋関数。インスタンス不要
文字列 / 数値 / 日付の変換ユーティリティstatic状態を持たない
状態(DB 接続 / 設定)を扱うインスタンスDI / モックがしやすい
同じ処理を多態的に切り替えるインスタンスオーバーライド可能
シングルトンの主要 APIインスタンス後で差し替え・テストしやすい

ユーティリティクラスの典型形

状態を持たない static メソッド群をまとめたクラスをユーティリティクラスと呼びます。インスタンス化を防ぐため、コンストラクタを private にします。

public final class StringUtils {
    private StringUtils() { /* インスタンス化禁止 */ }

    public static boolean isEmpty(String s) {
        return s == null || s.isEmpty();
    }

    public static String repeat(String s, int n) {
        StringBuilder sb = new StringBuilder(s.length() * n);
        for (int i = 0; i < n; i++) sb.append(s);
        return sb.toString();
    }
}

オーバーライドできないこと

サブクラスで同じシグネチャの static メソッドを定義しても、多態性は働きません。これを「メソッドの隠蔽(hiding)」と呼びます。呼び出されるのは変数の宣言型側のメソッドです。

class Animal {
    public static String name() { return "Animal"; }
}
class Dog extends Animal {
    public static String name() { return "Dog"; }
}

Animal a = new Dog();
System.out.println(a.name()); // → "Animal" (多態にならない)

static メソッドのテスト

static メソッドはインスタンス化不要で呼びやすい反面、差し替え(モック)が難しいです。テスト容易性のために:

  • 純粋関数(引数 → 戻り値のみ)として書く — モック不要
  • 状態や外部依存(時刻 / ファイル / 通信)はインスタンス側に閉じ込める
  • どうしても static で外部依存を持つ場合は、Mockito の mockStatic(推奨度は下がる)

static 初期化ブロックとの関係

static フィールドの初期化や、static メソッドが参照する定数の組み立てには static 初期化ブロックを使います。クラスが最初にロードされたタイミングで 1 回だけ実行されます。

public class Config {
    public static final Map<String, String> MAP;
    static {
        MAP = new HashMap<>();
        MAP.put("env", "prod");
        MAP.put("ver", "1.0");
    }
}

FAQ

Q: main メソッドはなぜ static?
A: プログラム開始時点ではまだ何のインスタンスも作られていないため、JVM がクラスから直接呼べる必要があるからです。

Q: static メソッド内で new はできる?
A: できます。インスタンス化自体は static メソッドでも自由です。

Q: なんでもかんでも static にして良い?
A: 推奨しません。状態を隠す手段が乏しく、テストや拡張が難しくなります。「引数 → 戻り値で完結する処理」だけ static にし、その他はインスタンスへ。

関連

  • staticについて — 親カテゴリ
  • static フィールド / static 初期化ブロック
  • final / private コンストラクタ — ユーティリティクラス定型
  • シングルトンパターン — インスタンスで「グローバル状態」を持つ別解
  • Math / Arrays / Collections — 標準ライブラリの static メソッド集
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. static変数
  2. static関数

最近更新/作成されたページ