【Java初心者向け】staticキーワードとは?インスタンス変数との違いを徹底解説 更新日: 2026年2月01日 私がJavaエンジニアとして駆け出しの頃、Webアプリのログイン機能を作っていて、とんでもないバグを生んでしまったことがあります。 「ログインしたユーザー名は、どこからでも参照できるように static にしておこう!」 そう安易に考えて、public static String currentUserName; という変数を作りました。 テスト環境で動作確認すると、最初は問題なく動いていました。しかし、複数人で同時にアクセスした瞬間、悲劇が起きました。 Aさんがログインした直後にBさんがログインすると、Aさんの画面に表示される名前も勝手に「Bさん」に書き換わってしまったのです。 つまり、サイトを使っている全ユーザーの名前が、最後にログインした人の名前に上書きされてしまうという、情報漏洩スレスレの大事故でした。 この失敗の原因は、static というキーワードが持つ「全員でたった一つを共有する」という恐ろしい性質を理解していなかったことにあります。 今日は、この static の本質を、「自動車工場」の例えで徹底的に解説します。 🚗 インスタンスとstatic:個々の車と、工場の生産記録 まず、staticではない通常の変数(インスタンス変数)と、staticな変数の違いをイメージで掴みましょう。 インスタンス変数: 車の「色」や「ナンバープレート」のように、作られた車(オブジェクト)それぞれが個別に持つ情報です。「私の赤い車」と「あなたの青い車」の色が違うのは、color がインスタンス変数だからです。 static変数: 自動車工場の「今日までに生産した総台数」のように、全ての車(オブジェクト)で共有される情報です。新しい車が1台作られるたびに、この「総台数」は1つ増えますが、どの車から見てもこの数字は同じです。 このイメージを念頭に、2つの使い方を見ていきましょう。 ① static変数:全オブジェクトで共有される「共有ロッカー」 staticを付けて宣言された変数(フィールド)は、特定のオブジェクトのものではなく、クラス全体でたった一つだけ存在します。 Carクラスを作って、この違いをコードで見てみましょう。 public class Car { // インスタンス変数(車ごとに異なる) String color; // static変数(全ての車で共有) public static int totalCarsProduced = 0; public Car(String color) { this.color = color; // 新しい車が1台作られるたびに、共有のカウンターを1増やす totalCarsProduced++; System.out.println(this.color + "の車が作られました。生産総台数: " + totalCarsProduced + "台"); } public static void main(String[] args) { System.out.println("工場稼働開始時の生産台数: " + Car.totalCarsProduced); // => 0 Car redCar = new Car("赤"); // => 生産総台数: 1台 Car blueCar = new Car("青"); // => 生産総台数: 2台 // インスタンス変数は、それぞれの車で異なる System.out.println("1台目の色: " + redCar.color); // => 赤 System.out.println("2台目の色: " + blueCar.color); // => 青 // static変数は、クラス名でアクセスするのが一般的 // どの車から見ても同じ値 System.out.println("現在の総生産台数: " + Car.totalCarsProduced); // => 2 } } 💡 冒頭のバグの原因 私がやってしまった失敗は、ユーザー名を totalCarsProduced のような「共有変数」にしてしまったことです。 本来、ユーザー名は color のように「個々のインスタンス(ユーザー)」ごとに持つべき情報でした。 ② staticメソッド:オブジェクト不要で呼び出せる「便利ツール」 staticを付けて宣言されたメソッドは、オブジェクトを生成(new)しなくても、いつでも呼び出すことができます。 これは、特定の車がなくても使える「自動車に関する計算ツール」のようなものです。 public class MathUtils { // 2つの数値を足すだけのシンプルな便利メソッド public static int add(int a, int b) { return a + b; } public static void main(String[] args) { // オブジェクトを作らずに、直接メソッドを呼び出せる int result = MathUtils.add(10, 20); System.out.println("10 + 20 = " + result); // => 30 // Java標準のMathクラスも、全てのメソッドがstatic double pi = Math.PI; // staticな定数 double sqrtValue = Math.sqrt(25); // staticなメソッド System.out.println("25の平方根は " + sqrtValue); // => 5.0 } } main メソッドが static である理由もこれで分かりますね。 Javaプログラムを実行する時、JVM(Java仮想マシン)は、まだ一つもオブジェクトが存在しない状態からスタートします。 もし main が static でなければ、JVMは「どのオブジェクトの main を呼べばいいの?」と困ってしまいます。static だからこそ、何もない状態からプログラムを開始できるのです。 🚨【最重要ルール】staticメソッドの制約 staticなメソッドの中からは、staticではないインスタンス変数やインスタンスメソッドを直接呼び出すことはできません。なぜなら、staticなメソッド(工場の放送室)は、個々の車(インスタンス)を知らないからです。「ある車の色を教えて」と言われても、「どの車のこと?」となってしまいます。これがstaticを扱う上で最も重要なルールです。 まとめ staticキーワードの謎は解けたでしょうか?その本質は、クラスという「設計図」に直接紐づく、特別なメンバーを定義することです。 static変数(フィールド): 全オブジェクトで共有されるデータ。クラスに一つだけ存在する。(私の失敗のように、個別の情報を入れてはいけません!) staticメソッド: オブジェクトがなくても直接呼び出せる便利機能。 staticを正しく理解することは、バグのない安全なコードを書くための第一歩です。 あなたの書くコードの中で、あるデータが「全インスタンスで共通であるべきか」、それとも「個別に持つべきか」を常に意識してみてください。 プログラミング学習に必須ツール! 記事で紹介したコードがよく分からなかったり、ご自身のコードについてもっと知りたい場合は、AIコード解説ツールが便利です。コードを貼り付けるだけで、AIが日本語で分かりやすく解説します。 AIコード解説ツールを使ってみる →