Javaの「非staticメソッドをstaticコンテキストから参照できません」エラーの原因と修正方法
多くのプログラマーがコーディング中に「Non-static method cannot be referenced from a static context(非staticメソッドはstaticコンテキストから参照できません)」というエラーメッセージに直面します。このエラーは特定のIDEに限定されたものではなく、条件が揃えばどの開発環境でも発生する可能性があります。
これは初心者に非常によくあるミスで、クラスのインスタンスを生成せずにクラスを「静的(static)」に扱おうとした場合に発生します。staticなクラスやメソッドを使用する際には、満たすべき条件がいくつかあります。本記事では、代表的なケースを挙げながら、staticメソッドの正しい使い方とエラーの解決方法を詳しく解説します。
staticメソッドとは何か?
メソッドに「static」というキーワードを付けると、そのメソッドはstaticメソッド(静的メソッド)になります。通常のメソッドがオブジェクト(インスタンス)に属するのに対し、staticメソッドはクラス自体に属します。そのため、クラスのインスタンスを生成しなくても直接呼び出すことができるのが大きな特徴です。
staticメソッドにはさまざまな用途があります。例えば、staticなデータメンバー(クラス変数)の値を変更したり、すべてのオブジェクトに共通する処理を実行したりできます。ただし、staticメソッドには制限もあります。クラスの非staticフィールド(インスタンス変数)にアクセスしたい場合は、必ず非staticメソッドを使う必要があります。つまり、staticメソッドは頻繁に使うものではありませんが、適切に使えば非常に便利です。
以下は、staticメソッドを使ってすべてのオブジェクトのプロパティを変更する簡単なサンプルコードです。
class Students {
int roll_no;
String name;
static String college = "InformationTech";
static void change() {
college = "Management";
}
Students(int number, String name_self) {
roll_no = number;
name = name_self;
}
void display() { System.out.println(roll_no + " " + name + " " + college); }
public static void main(String args[]) {
Students.change();
Students stu_1 = new Students(100, "Mexican");
Students stu_2 = new Students(202, "American");
Students stu_3 = new Students(309, "British");
stu_1.display();
stu_2.display();
stu_3.display();
}
}このプログラムの出力結果は以下のようになります。
100 Mexican Management 202 American Management 309 British Management
クラスとインスタンスの違いとは?
街を歩いていて車を見かけたとき、モデルや型式を知らなくても「それは車だ」とすぐに分かります。これは、あなたがすでに知っている「車」というクラス(概念)に属していると認識できるからです。ここでのクラスとは、テンプレートや設計図のようなイメージです。
近づいて車種やメーカーを確認すると、今度は「車」というクラスのインスタンス(実体)を認識していることになります。この段階では、ホイール、馬力、ホイールのデザインなど、すべての属性が具体的な詳細として存在しています。
属性の一例を挙げると、「車」というクラスでは「すべての車にはホイールが必要である」と定義されています。そして、目の前にある車(Carクラスのインスタンス)にはアルミホイールが装着されている、といった具合です。
オブジェクト指向プログラミングでは、クラスを自分で定義し、その中に「color(色)」のような型のフィールドを宣言します。クラスがインスタンス化されると、バックエンドで自動的にcolor用のメモリが確保され、後から具体的な値(例えば「赤」)を設定できます。このような個別の属性はインスタンスごとに異なるため、非staticとして扱われます。
一方、staticなメソッドやフィールドは、すべてのインスタンス間で共有されます。これらは、インスタンスではなくクラス固有の値や項目のために用意されるものです。メソッドであれば文字列を整数に変換するユーティリティのようなグローバルな処理が該当し、フィールドであれば定数などが典型例です(例えば、普通車のみを製造しているなら「車種」をstaticにできるでしょう)。
それでは、実際にコーディングでミスが起こりやすいケースと、それぞれの回避策を見ていきましょう。
ケース1:存在しないものを呼び出そうとしている
staticメソッドと非staticメソッドを混在させて使用するケースがあります。この場合、どのメソッドが何を呼び出しているのか(それがstaticかどうか)を意識することが重要です。以下のコードを見てください。
private java.util.List<String> someMethod(){
/* 何らかの処理 */
return someList;
}
public static void main(String[] strArgs){
// 次のステートメントがエラーを引き起こします。理由は分かりますね?
java.util.List<String> someList = someMethod();
}この例では、staticメソッドであるmainから非staticメソッドsomeMethodを呼び出しています。オブジェクト指向プログラミングでは、データと、そのデータに対して操作を行う処理をひとまとめにしてカプセル化します。オブジェクトが存在しなければインスタンスデータも存在せず、インスタンスメソッドはクラス定義の一部として存在していても、常にオブジェクトのインスタンスがデータを提供する必要があります。
まとめると、存在しないものを呼び出すことはできません。オブジェクトを生成していなければ、非staticメソッドはまだ存在しないのです。一方、staticメソッドは定義上、常に存在しています。
ケース2:メソッドがstaticになっていない
staticなmainメソッドから、インスタンスを生成せずに他のメソッドを呼び出すと、エラーメッセージが表示されます。ここでも同じ原則が適用されます。存在しないものにはアクセスできないのです。
public class BookStoreApp2 {
// 選択肢用の定数
Scanner input = new Scanner(System.in);
public static void main(String[] args) {
BookStoreItem[] item; // 配列の宣言
item = new BookStoreItem[10]; // 配列の初期化
int itemType = -1;
printMenu();
getUserChoice();
for (int i = 0; i < item.length; i++) {
} // switch文の終わり
} // forループの終わり
for (int i = 0; i < item.length; i++) {
} // forの終わり
} // mainメソッドの終わりこのコードの場合、printMenu()とgetUserChoice()の両方のメソッドをstaticメソッドに変更する必要があります。
また、このような状況を回避したい場合は、代わりにコンストラクタを使う方法もあります。例えば、main()メソッドの中身をコンストラクタ内に移動させるのです。
public BookStoreApp2()
{
// mainメソッドの中身をここに記述する
}その後、main()メソッド内で以下のように記述します。
public void main(String[] args)
{
new BookStoreApp2();
}これらのヒントがうまく機能しない場合や、コードの構造が異なる場合は、staticクラスおよびstaticメソッドの基本原則を思い出し、コードを見直して基本原則に違反していないか確認してください。「staticな文脈からは、インスタンスなしで非staticなメンバーにはアクセスできない」という原則さえ守れば、このエラーは確実に解消できます。
-
Fallout 76で「サーバーから切断される」エラーを解決する6つの対処法
Fallout 76は、Bethesda Studiosが2018年にリリースした人気のマルチプレイRPGアクションゲームです。Windows PC、Xbox One、PlayStation 4向けに提供されており、Falloutシリーズが好きな方ならきっと楽しめる作品でしょう。しかし、多くのプレイヤーから「PCでゲームを起動しようとした際に、Fallout 76がサーバーから切断される」というエラーが報告されています。Bethesda Studiosによると、この問題はサーバーへの過負荷、つまり多数のプレイヤーが同時にアクセスしたことが原因であるとされています。ただし、同じエラーに悩まされて
-
Windows 10でセカンダリミラードライブから起動できない問題を修正する方法【完全解説】
このチュートリアルでは、Windows 10パソコンで起動ドライブが「ミラー機能(ソフトウェアRAID-1)」によりミラー化されている環境において、プライマリドライブが起動しなくなった、または破損した際に、セカンダリミラードライブからシステムを起動できない問題を解決する方法を詳しくご紹介します。 問題の内容 セカンダリのミラー起動ディスクからWindowsを起動しようとすると、エラーコード 0x000000e のブルースクリーン(BSOD)が表示され、以下のようなメッセージが出ます。 「PC/デバイスを修復する必要があります。必要なデバイスが接続されていないか、アクセスできません。」 このガ