タイトル: static関数
SEOタイトル: Java static メソッド 完全ガイド(インスタンス不要 / クラスメソッド / 使い分け / オーバーライド不可 / ユーティリティクラス)
| この記事の要点 |
|
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 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 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 メソッド集