web-dev-qa-db-ja.com

メソッドパラメータの名前を取得する

Java 6では、次のメソッドシグネチャがあるとします。

public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard)

実行時に、slice2またはその他のパラメーターに渡された値を知りたいのですが、ここで重要なのは、パラメーター名で値を取得することです。

getParameterTypesまたはgetGenericParameterTypesを使用してパラメータータイプのリストを取得する方法を知っています。

タイプの代わりにパラメーターnamesのリストを取得したいのですが。そうする方法はありますか?

25
Tiago Veloso

パラメータ名は、コンパイラに含めるように指示した場合に使用できます(デバッグ情報を使用してコンパイル)。 Springには ParameterNameDiscoverer があり、名前を取得するのに役立ちます。 デフォルトの実装 は、asm ClassReader を使用して行います。

javacでは、_-g_引数を含めてデバッグ情報を含める必要があります。 Eclipseでは、デフォルトで存在すると思います。これは設定を使用して構成できます:Java->コンパイラー、次に「メソッドパラメーターに関する情報を保存(リフレクションを介して使用可能)」を有効にします( この回答 も参照)。

一部のフレームワークはこれを使用します。たとえば、spring-mvcには_@RequestParam_があり、解決可能な場合はデフォルトでパラメーター名になります。また、デバッグ情報が提供されない場合の明示的な命名-@RequestParam("foo")もサポートします。

48
Bozho

この質問に回答済みのマークを付けた後、別の解決策を見つけました。解決策は Paranamer です。

例:

 Method method = Foo.class.getMethod(...);

 Paranamer paranamer = new CachingParanamer();

 String[] parameterNames = paranamer.lookupParameterNames(method) // throws ParameterNamesNotFoundException if not found

 // or ...

 parameterNames = paranamer.lookupParameterNames(method, false) // will return null if not found
11
Tiago Veloso

this の回答に加えて、「パラメーター名は、コンパイラーに含めるように指示した場合に使用できます」

Eclipseを使用している場合は、プロジェクトに移動します->プロパティ-> Javaコンパイラ->「メソッドパラメータに関する情報を保存します(リフレクションを介して使用可能)」

4
Denis K

Java 1.8なので、これは実行できますパラメータ名がクラスファイルにある限りjavacを使用すると、-parameters 国旗。 javacヘルプから

-parameters    Generate metadata for reflection on method parameters

IDEからは、コンパイラの設定を確認する必要があります。

パラメータ名がクラスファイルにある場合、これはこれを行う例です

import Java.lang.reflect.Method;
import Java.lang.reflect.Parameter;

public class ParameterNamesExamples {

  public static void main(String[] args) throws Exception {
    Method theDoSomethingMethod = ExampleClass.class.getMethods()[0];
    // Now loop through the parameters printing the names
    for(Parameter parameter : theDoSomethingMethod.getParameters()) {
      System.out.println(parameter.getName());
    }
  }

  private class ExampleClass {
    public void doSomething(String myFirstParameter, String mySecondParameter) {
      // No-op
    }
  }
}

出力はパラメータ名がクラスファイルにある場合によって異なります。それらが出力である場合:

myFirstParameter
mySecondParameter

そうでない場合、出力は次のとおりです。

arg0
arg1

Oracleからのこれに関する詳細情報は、 メソッドパラメータの名前の取得 にあります。

3
James Mudd

これは不可能です。ソースが使用できないときにIDEのオートコンプリートで確認できるように、クラスファイルには引数名は含まれていません。

したがって、リフレクションAPIはパラメーター名を提供できません。

2
slaphappy

Javaパラメータ名は、リフレクションでは使用できません。

2

パラメータの値を別の値に割り当てるだけです

Bread slice2;

public void makeSandwich(Bread slice1, Bread slice2, List<Filling> fillings, boolean mustard) {
    this.slice2 = slice2;
    System.out.println(this.slice2.getSomething());
}
0
mastaH

メソッドのコードを所有していますか?パラメータに注釈を付け、名前を引数@Param("slice1")として渡すことができます。後で、アノテーションを取得して、そこからパラメーター名を抽出できます。

0
denis.solonenko