web-dev-qa-db-ja.com

Javaで静的メソッドからgetClass()を呼び出す方法?

いくつかの静的メソッドを持たなければならないクラスがあります。これらの静的メソッド内では、次の呼び出しを行うためにメソッド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

このコンパイル時エラーを修正するための適切な方法は何ですか?

311
Rama

getClass()の代わりにTheClassName.classを使うだけです。

547
Mark Peters

問題のコード例に関して、標準的な解決策はクラスをその名前で明示的に参照することです、そしてそれはgetClassLoader()呼び出しなしですることさえ可能です:

class MyClass {
  public static void startMusic() {
    URL songPath = MyClass.class.getResource("background.midi");
  }
}

このアプローチには、このコードをいくつかの類似したクラスに複製する必要がある場合に備えて、コピー/貼り付けエラーに対してそれほど安全ではないという欠点があります。

そして見出しの正確な質問に関しては、 隣接するスレッドに投稿されたトリックがあります

Class currentClass = new Object() { }.getClass().getEnclosingClass();

実行コンテキストを把握するために、ネストした匿名のObjectサブクラスを使用します。このトリックには、コピー/貼り付けが安全であるという利点があります。

他のクラスが継承している基本クラスでこれを使用する場合の注意:

このスニペットがある基本クラスの静的メソッドとして形成されている場合、currentClass値は、そのメソッドを使用している可能性のあるサブクラスではなく、常にその基本クラスへの参照になります。

104
Sergey Ushakov

Java 7以降では、静的メソッド/フィールドでこれを行うことができます。

MethodHandles.lookup().lookupClass()
56
Rein

私はこれを自分で取り組んだ。ナイストリックは、静的コンテキストで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;
}
18
starkadder

単にクラスリテラル、すなわちNameOfClass.classを使う

13

getClass()メソッドは、以下のシグネチャでObjectクラスに定義されています。

パブリックファイナルクラスgetClass()

staticとして定義されていないため、静的コードブロック内で呼び出すことはできません。詳細については、これらの回答を参照してください。 Q1Q2Q3

もしあなたが静的な文脈にいるのなら、Classを取得するためにクラスリテラル式を使わなければならないので、基本的に次のようにしなければなりません:

Foo.class

このような式はクラスリテラルと呼ばれ、次のように Java言語仕様書 で説明されています。

クラスリテラルは、クラス名、インタフェース名、配列名、またはプリミティブ型の後に `。 'を続けたものです。そしてトークンクラス。クラスリテラルの型はClassです。現在のインスタンスのクラスの定義クラスローダで定義されている名前付きタイプ(またはvoid)のClassオブジェクトに評価されます。

この件に関する情報はClassの APIドキュメント にもあります。

9
melihcelik

それを試してみてください

Thread.currentThread().getStackTrace()[1].getClassName()

または

Thread.currentThread().getStackTrace()[2].getClassName()
5
Ishfaq