non-static variable cannot be referenced の原因と直し方
staticとインスタンスの境界。mainから他のメンバーを呼ぶときの3つの選択肢を比較します。
エラーメッセージの読み方
Main.java:5: error: non-static variable count
Main.java- ファイル名
5- 行番号 — javacが異常に気づいた位置。原因の行とは限りません
error- 種別 — コンパイルエラー。実行まで到達しません
non-static variable count- 内容 — javacが期待していたもの、または見つけられなかったもの
このエラーが出る典型パターン
パターン1
1 public class Main { 2 int count = 10; 3 4 public static void main(String[] args) { 5 System.out.println(count ); ^ 6 } 7 }
Main.java:5: error: non-static variable count
cannot be referenced from a static context
countはインスタンスごとの変数ですが、mainはstaticなので「どのMainか」が決まりません。
直し方: count を new Main().count にします。
広告
広告スロット(未設定)
パターン2
1 public class Main { 2 void greet() { 3 System.out.println("hi"); 4 } 5 public static void main(String[] args) { 6 this .greet(); ^ 7 } 8 }
Main.java:6: error: non-static variable this cannot be referenced from a static context
staticメソッドの中にthisは存在しません。インスタンスメソッドを呼ぶには実体が要ります。
直し方: this を new Main() にします。
パターン3
1 public class Main { 2 int LIMIT = 100; ^ 3 4 public static void main(String[] args) { 5 System.out.println(LIMIT); 6 } 7 }
Main.java:5: error: non-static variable LIMIT cannot be referenced from a static context
staticなmainから直接使いたい変数はstaticにします。定数は static final にするのが慣習です。
直し方: (空) を static にします。
パターン4
1 public class Main { 2 void run() { System.out.println("running"); } 3 public static void main(String[] args) { 4 run (); ^ 5 } 6 }
Main.java:4: error: non-static method run() cannot be referenced from a static context
インスタンスメソッドはstaticから直接呼べません。実体を作ってから呼びます。
直し方: run を new Main().run にします。
パターン5
1 public class Main { 2 int id = 1; 3 static void show() { 4 System.out.println(id ); ^ 5 } 6 public static void main(String[] args) { 7 show(); 8 } 9 }
Main.java:4: error: non-static variable id
cannot be referenced from a static context
staticメソッドの中では、mainに限らずインスタンスの変数へ直接アクセスできません。
直し方: id を new Main().id にします。
よくある誤解
staticを足せばエラーは消えますが、それが正しいとは限りません。多くの場合、設計を見直す合図です。
実務での勘所
static修飾子を安易に付けて解決した場合、後で別の問題を生むことがあります。staticメソッドは継承先でオーバーライドできず、同名のstaticメソッドを子クラスに書いても「隠蔽(hiding)」という別の扱いになり、ポリモーフィズムが効きません。「動かしたいだけならstaticを付ければいい」という対処を繰り返すと、後からオブジェクト指向的な多態性を使いたくなったときに設計をやり直す羽目になります。