Могу ли я получить имя параметра метода, используя отражение Java? - PullRequest
111 голосов
/ 10 февраля 2010

Если у меня есть такой класс:

public class Whatever
{
  public void aMethod(int aParam);
}

есть ли способ узнать, что aMethod использует параметр с именем aParam, который имеет тип int?

Ответы [ 14 ]

90 голосов
/ 15 декабря 2013

В Java 8 вы можете делать следующее:

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

public final class Methods {

    public static List<String> getParameterNames(Method method) {
        Parameter[] parameters = method.getParameters();
        List<String> parameterNames = new ArrayList<>();

        for (Parameter parameter : parameters) {
            if(!parameter.isNamePresent()) {
                throw new IllegalArgumentException("Parameter names are not present!");
            }

            String parameterName = parameter.getName();
            parameterNames.add(parameterName);
        }

        return parameterNames;
    }

    private Methods(){}
}

Так что для вашего класса Whatever мы можем сделать ручной тест:

import java.lang.reflect.Method;

public class ManualTest {
    public static void main(String[] args) {
        Method[] declaredMethods = Whatever.class.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals("aMethod")) {
                System.out.println(Methods.getParameterNames(declaredMethod));
                break;
            }
        }
    }
}

, который должен вывести [aParam], если вы передали -parameters аргумент вашему компилятору Java 8.

Для пользователей Maven:

<properties>
    <!-- PLUGIN VERSIONS -->
    <maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>

    <!-- OTHER PROPERTIES -->
    <java.version>1.8</java.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <!-- Original answer -->
                <compilerArgument>-parameters</compilerArgument>
                <!-- Or, if you use the plugin version >= 3.6.2 -->
                <parameters>true</parameters>
                <testCompilerArgument>-parameters</testCompilerArgument>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

Для получения дополнительной информации см. Следующие ссылки:

  1. Официальное руководство по Java: получение имен параметров метода
  2. JEP 118: доступ к именам параметров во время выполнения
  3. Javadoc для класса параметров
78 голосов
/ 10 февраля 2010

Подведем итог:

  • получение имен параметров возможно возможно, если во время компиляции включена отладочная информация. См. этот ответ для более подробной информации
  • в противном случае получение имен параметров не возможно
  • возможно получить тип параметра, используя method.getParameterTypes()

Для написания функций автозаполнения для редактора (как вы указали в одном из комментариев) есть несколько вариантов:

  • использование arg0, arg1, arg2 и т. Д.
  • использование intParam, stringParam, objectTypeParam и т. Д.
  • используйте комбинацию вышеперечисленного - первый для не примитивных типов и последний для примитивных типов.
  • вообще не показывает имена аргументов - только типы.
14 голосов
/ 22 февраля 2010

Библиотека Paranamer была создана для решения этой же проблемы.

Она пытается определить имена методов несколькими различными способами.Если класс был скомпилирован с отладкой, он может извлечь информацию, прочитав байт-код класса.

Другой способ - внедрить закрытый статический член в байт-код класса после его компиляции, но доэто помещено в банку.Затем он использует отражение для извлечения этой информации из класса во время выполнения.

https://github.com/paul-hammant/paranamer

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

9 голосов
/ 02 сентября 2015

Да.
Код должен быть скомпилирован с помощью совместимого с Java 8 компилятора с включенной опцией хранения формальных имен параметров (опция -parameters ).
Тогда этот фрагмент кода должен работать:

Class<String> clz = String.class;
for (Method m : clz.getDeclaredMethods()) {
   System.err.println(m.getName());
   for (Parameter p : m.getParameters()) {
    System.err.println("  " + p.getName());
   }
}
7 голосов
/ 09 сентября 2014

см. Org.springframework.core.DefaultParameterNameDiscoverer class

DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] params = discoverer.getParameterNames(MathUtils.class.getMethod("isPrime", Integer.class));
5 голосов
/ 10 февраля 2010

Вы можете получить метод с отражением и определить его типы аргументов.Проверьте http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html#getParameterTypes%28%29

Однако вы не можете сказать имя используемого аргумента.

3 голосов
/ 15 января 2013

См. java.beans.ConstructorProperties , это аннотация, предназначенная именно для этого.

3 голосов
/ 16 апреля 2012

Хотя это невозможно (как проиллюстрировали другие), вы могли бы использовать аннотацию для переноса имени параметра и получить его через отражение.

Не самое чистое решение, но оно выполняет свою работу. Некоторые веб-сервисы фактически делают это для сохранения имен параметров (например, развертывание WS с помощью glassfish).

3 голосов
/ 11 февраля 2010

Это возможно, и Spring MVC 3 делает это, но я не торопился, чтобы понять, как именно.

Соответствие имен параметров метода к именам переменных шаблона URI можно только если ваш код скомпилирован с включенной отладкой. Если у вас есть не включена отладка, необходимо укажите имя шаблона URI имя переменной в @PathVariable аннотация для того, чтобы связать разрешенное значение имени переменной в параметр метода. Например:

Взято из пружинной документации

2 голосов
/ 23 мая 2016

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

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...