Получение имени параметра метода - PullRequest
20 голосов
/ 20 июля 2011

В Java 6 , представьте, что у меня есть следующая сигнатура метода:

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

Я хотел бы знать, во время выполнения, значение, которое было передано slice2 или любому другому параметру, важный бит здесь в том, что я хочу получить значение по имени параметра.

Я знаю, как получить список типов параметров с помощью getParameterTypes или getGenericParameterTypes.

В идеале я хотел бы получить список параметров names вместо типов. Есть ли способ сделать это?

Ответы [ 8 ]

45 голосов
/ 20 июля 2011

Имена параметров доступны, если вы сказали компилятору включить их (скомпилируйте с отладочной информацией).Spring имеет ParameterNameDiscoverer, который может помочь вам получить имена.Реализация по умолчанию использует для этого asm ClassReader.

В javac необходимо включить аргумент -g для включения информации отладки.С Eclipse я думаю, что он там по умолчанию;его можно настроить с помощью параметров: Java -> Компилятор и затем включить «Хранить информацию о параметрах метода (можно использовать для отражения)» (см. также этот ответ ).

Некоторые платформы используют это,Например, spring-mvc имеет @RequestParam, по умолчанию используется имя параметра, если оно разрешаемо.Он также поддерживает явное именование - @RequestParam("foo") в случае, если не предоставлена ​​отладочная информация.

10 голосов
/ 21 июля 2011

Я нашел другое решение после пометки этого вопроса как ответа. Решение 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
2 голосов
/ 04 мая 2016

В дополнение к этот ответ: «Имена параметров доступны, если вы сказали компилятору включить их»

Если вы используете Eclipse, перейдите в проект -> свойства ->Компилятор Java -> check "Хранить информацию о параметрах метода (используется через отражение)

2 голосов
/ 20 июля 2011

В Java имена параметров не доступны через отражение.

2 голосов
/ 20 июля 2011

Это невозможно.Файлы классов не содержат имен аргументов, как вы можете видеть по автозаполнению вашей IDE, когда источник недоступен.

Следовательно, API отражения не может выдавать имена параметров.

0 голосов
/ 22 марта 2019

Начиная с 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 можно найти по адресу Получение имен параметров метода

0 голосов
/ 20 июля 2011

У вас есть код метода? Вы можете аннотировать параметры и передавать имена в качестве аргументов @Param("slice1"). Позже вы сможете получить аннотацию и извлечь из нее имя параметра.

0 голосов
/ 20 июля 2011

Вы можете просто присвоить значение параметра другому значению

Bread slice2;

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