前回はアクセス修飾子を深掘りしました。
今回は「static」について整理します。static はよく使う反面、誤った使い方をするとバグの原因になりやすいキーワードです。
staticとは
static をつけたフィールド・メソッドはインスタンスではなくクラスに属します。インスタンスを作らなくても使え、すべてのインスタンスで共有されます。
static field → クラスで1つだけ存在する変数
static method → インスタンスなしで呼べるメソッド
static block → クラスロード時に1度だけ実行される初期化処理
サンプルコード
ファイル作成
「Java66」フォルダに StaticTest.java という名前でファイルを作成します

コード入力
public class StaticTest {
// staticフィールド: すべてのインスタンスで共有
static int instanceCount = 0;
static final double TAX_RATE = 0.1; // 定数はstatic final
// インスタンスフィールド: インスタンスごとに独立
String name;
// staticブロック: クラスロード時に1度だけ実行
static {
System.out.println("クラスがロードされました");
}
StaticTest(String name) {
this.name = name;
instanceCount++; // インスタンスが作られるたびにカウント
}
// staticメソッド: インスタンスなしで呼べる
static int getInstanceCount() {
return instanceCount;
}
// staticメソッド: インスタンス変数にはアクセスできない
static double calcTax(int price) {
return price * TAX_RATE;
// return name; // エラー: staticメソッドからインスタンス変数は使えない
}
// インスタンスメソッド: staticフィールドにもアクセスできる
void describe() {
System.out.println(name + "(通算" + instanceCount + "番目)");
}
public static void main(String[] args) {
System.out.println("インスタンス数: " + StaticTest.getInstanceCount());
StaticTest a = new StaticTest("ぱんまる");
StaticTest b = new StaticTest("たろう");
StaticTest c = new StaticTest("はなこ");
a.describe();
b.describe();
c.describe();
System.out.println("合計インスタンス数: " + StaticTest.getInstanceCount());
System.out.println("税額(1000円): " + StaticTest.calcTax(1000) + "円");
}
}

コンパイル
javac StaticTest.java

実行
java StaticTest
実行結果は次のようになります。
クラスがロードされました
インスタンス数: 0
ぱんまる(通算3番目)
たろう(通算3番目)
はなこ(通算3番目)
合計インスタンス数: 3
税額(1000円): 100.0円

staticを使うべき場面・避けるべき場面
使うべき場面:
・定数(static final)
・ユーティリティメソッド(Math.abs、Collections.sortなど)
・ファクトリメソッド
・カウンターなど全インスタンスで共有したい値
避けるべき場面:
・状態を持つ処理(マルチスレッドで競合が起きやすい)
・テストしにくいコード(staticはモック化が難しい)
・なんでもstaticにする「静的クラス乱用」
まとめ
static はクラスに属するフィールド・メソッドを定義します。定数・ユーティリティ・カウンターなど適切な場面で使うことで便利ですが、状態を持つ処理やテストが必要なコードには使いすぎないようにしましょう。インスタンスメソッドはstaticフィールドにアクセスできますが、staticメソッドからインスタンス変数へのアクセスはできない点も覚えておきましょう。
2026/08/26(水) ぱんまる

コメント