0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Javaのstaticメソッドについて調べてみた

Posted at

はじめに

新卒サーバエンジニアのRenです。
研修でJavaを学習している際、同じMainクラス内のメソッドをmainメソッドから呼び出そうとしたところ、コンパイルエラーが発生しました。
理由は呼び出し先のメソッドにstaticをつけていなかったこと。
この機会にstaticについて調べてみたので共有します。


TL;DR

  • main は「まだオブジェクトが無い状態」で呼ばれるため static
  • static コンテキストでは this が存在しない → 非-static メソッドは直呼びできずエラー
  • 解決策は「① 呼び出し先も static 」「② オブジェクトを生成して呼ぶ」の 2 つ
  • static は便利だが乱用は設計とテストを壊す。必要条件を満たすときだけ使う

目次

  1. 症状の再現コードとエラーメッセージ
  2. static コンテキストとは?
  3. 解決策
  4. そもそも static とは何者か
  5. static のメリット/デメリット
  6. 実践での static の使いどころ 5 選
  7. まとめ ― “必要なときだけ static” のススメ

症状の再現コードとエラーメッセージ

public class Main {
    public static void main(String[] args) {
        hello();              // ← コンパイルエラー!
    }

    void hello() {
        System.out.println("こんにちは");
    }
}
error: non-static method hello() cannot be referenced from a static context

main は呼べるのに hello は呼べない――この謎を解く鍵が static です。


static コンテキストとは?

視点 static コンテキスト 非-static コンテキスト
存在するもの クラスのみ(this なし) this(インスタンス参照)
呼び出せるメソッド static メソッド static + 非-static
代表例 public static void main toString(), equals()

JVM はプログラム起動時に

  1. クラスをロード
  2. オブジェクトを作らずに Main.main を呼び出す

という手順を踏みます。
つまり main が実行される瞬間 this は存在しない → 非-static メソッドを解決できずエラーになります。


解決策

① 呼び出し先も static にする

public class Main {
    public static void main(String[] args) {
        hello();           // OK
    }

    static void hello() {  // ← クラスメソッド化
        System.out.println("こんにちは");
    }
}

② インスタンスを生成して呼ぶ

public class Main {
    public static void main(String[] args) {
        new Main().hello();   // OK
    }

    void hello() {
        System.out.println("こんにちは");
    }
}

そもそも static とは何者か

定義: インスタンス(this)ではなく クラスそのもの に属するメンバ。

メモリとライフサイクル

┌─ クラスロード時(1回だけ) ─────────────┐
│  メタ領域 … static フィールド/メソッド   │
└──────────────────────────┘
       │          (プログラム実行中)
       ▼
┌──────── ヒープ ────────┐
│ new Main() ごとに        │
│   インスタンス領域        │
└────────────────────┘

主な性質

項目 static 非-static
帰属 クラス インスタンス
個数 1 クラス 1 個 new するたび
参照方法 Main.count obj.count
オーバーライド 不可(隠蔽のみ) 可能(ポリモーフィズム)

static のメリット/デメリット

メリット デメリット
1 インスタンス不要 → 軽量に即呼び出し グローバル変数化で依存が散乱
2 全オブジェクト間でデータ共有 可変データは競合条件の温床
3 Math.max などユーティリティ API をまとめやすい 動的ディスパッチ不可 → テストがしにくい
4 クラス単位で一度だけ初期化 クラスがアンロードされるまで GC 不可

実践での static の使いどころ 5 選

用途 ポイント
エントリポイント public static void main JVM から直接叩かれる
定数 public static final String VERSION final とセットで不変に
ユーティリティ関数 Math.sqrt, Collections.sort 状態を持たない純関数
シングルトン保持 private static final Logger LOG 全クラスで 1 個だけ共有
ファクトリメソッド List.of(...) (Java 9+) new を隠蔽し可読性向上

まとめ ― “必要なときだけ static” のススメ

  1. main は static コンテキストthis 不在 → 非-static を直呼びするとコンパイルエラー。
  2. 解決策は
    • 呼び出し先を static にする
    • インスタンスを生成して呼ぶ
  3. static は クラス単位で共有したい振る舞い・データ に限定して使う。
  4. 乱用すると 密結合・テスト困難・スレッド競合など副作用が噴出するため要注意。

「そのメソッドはオブジェクト固有の状態に触れるか?」

  • Yes → インスタンスメソッド
  • No → static メソッド

この記事が「main と static のモヤモヤ」を晴らす一助になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?