いくつかの静的メソッドを持たなければならないクラスがあります。これらの静的メソッド内では、次の呼び出しを行うためにメソッドgetClass()を呼び出す必要があります。
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
しかしEclipseは私にこう言います:
Cannot make a static reference to the non-static method getClass()
from the type Object
このコンパイル時エラーを修正するための適切な方法は何ですか?
getClass()
の代わりにTheClassName.class
を使うだけです。
問題のコード例に関して、標準的な解決策はクラスをその名前で明示的に参照することです、そしてそれはgetClassLoader()
呼び出しなしですることさえ可能です:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
このアプローチには、このコードをいくつかの類似したクラスに複製する必要がある場合に備えて、コピー/貼り付けエラーに対してそれほど安全ではないという欠点があります。
そして見出しの正確な質問に関しては、 隣接するスレッドに投稿されたトリックがあります :
Class currentClass = new Object() { }.getClass().getEnclosingClass();
実行コンテキストを把握するために、ネストした匿名のObject
サブクラスを使用します。このトリックには、コピー/貼り付けが安全であるという利点があります。
他のクラスが継承している基本クラスでこれを使用する場合の注意:
このスニペットがある基本クラスの静的メソッドとして形成されている場合、currentClass
値は、そのメソッドを使用している可能性のあるサブクラスではなく、常にその基本クラスへの参照になります。
Java 7以降では、静的メソッド/フィールドでこれを行うことができます。
MethodHandles.lookup().lookupClass()
私はこれを自分で取り組んだ。ナイストリックは、静的コンテキストでClassLoaderを取得するために現在のスレッドを使用することです。これはHadoop MapReduceでも機能します。他のメソッドはローカルで実行しても機能しますが、MapReduceで使用した場合はnullのInputStreamを返します。
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
単にクラスリテラル、すなわちNameOfClass.class
を使う
getClass()
メソッドは、以下のシグネチャでObjectクラスに定義されています。
パブリックファイナルクラスgetClass()
static
として定義されていないため、静的コードブロック内で呼び出すことはできません。詳細については、これらの回答を参照してください。 Q1 、 Q2 、 Q3 。
もしあなたが静的な文脈にいるのなら、Classを取得するためにクラスリテラル式を使わなければならないので、基本的に次のようにしなければなりません:
Foo.class
このような式はクラスリテラルと呼ばれ、次のように Java言語仕様書 で説明されています。
クラスリテラルは、クラス名、インタフェース名、配列名、またはプリミティブ型の後に `。 'を続けたものです。そしてトークンクラス。クラスリテラルの型はClassです。現在のインスタンスのクラスの定義クラスローダで定義されている名前付きタイプ(またはvoid)のClassオブジェクトに評価されます。
この件に関する情報はClassの APIドキュメント にもあります。
それを試してみてください
Thread.currentThread().getStackTrace()[1].getClassName()
または
Thread.currentThread().getStackTrace()[2].getClassName()