[java] Java 리플렉션을 사용하여 메소드 매개 변수 이름을 얻을 수 있습니까?

다음과 같은 수업이있는 경우 :

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

유형 aMethod의 매개 변수 를 사용하는 것을 알 수있는 방법이 있습니까?aParamint



답변

요약:

  • 매개 변수 이름을 얻는 것은 이다 디버그 정보를 컴파일하는 동안 포함 된 경우 가능합니다. 자세한 내용은 이 답변 을 참조하십시오.
  • 그렇지 않으면 매개 변수 이름을 가져올없습니다.
  • 매개 변수 유형을 가져올 수 있습니다. method.getParameterTypes()

(주석 중 하나에서 언급했듯이) 편집기의 자동 완성 기능을 작성하기 위해 몇 가지 옵션이 있습니다.

  • 사용 arg0, arg1, arg2
  • 사용 intParam, stringParam, objectTypeParam, 등
  • 위의 조합을 사용하십시오. 전자는 기본이 아닌 유형에 대해, 후자는 기본 유형에 대해 사용합니다.
  • 인수 이름을 전혀 표시하지 않고 유형 만 표시합니다.

답변

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;
            }
        }
    }
}

Java 8 컴파일러에 인수를 [aParam]전달한 경우 인쇄 해야합니다 -parameters.

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. 공식 자바 튜토리얼 : 메소드 매개 변수의 이름 얻기
  2. JEP 118 : 런타임시 매개 변수 이름에 액세스
  3. 매개 변수 클래스 용 Javadoc

답변

이 같은 문제를 해결하기 위해 Paranamer 라이브러리가 만들어졌습니다.

몇 가지 다른 방법으로 메서드 이름을 결정하려고합니다. 클래스가 디버깅으로 컴파일 된 경우 클래스의 바이트 코드를 읽어 정보를 추출 할 수 있습니다.

또 다른 방법은 컴파일 된 후 jar에 배치되기 전에 전용 정적 멤버를 클래스의 바이트 코드에 삽입하는 것입니다. 그런 다음 리플렉션을 사용하여 런타임에 클래스에서이 정보를 추출합니다.

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

이 라이브러리를 사용하는 데 문제가 있었지만 결국 작동하게되었습니다. 관리자에게 문제를보고하고 싶습니다.


답변

org.springframework.core.DefaultParameterNameDiscoverer 클래스 참조

DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] params = discoverer.getParameterNames(MathUtils.class.getMethod("isPrime", Integer.class));


답변

예. 형식 매개 변수 이름을 저장하는 옵션이 설정된 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());
   }
}


답변

리플렉션을 사용하여 메서드를 검색하고 인수 유형을 감지 할 수 있습니다. http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html#getParameterTypes%28%29 확인

그러나 사용 된 인수의 이름은 말할 수 없습니다.


답변

가능하고 Spring MVC 3가 그것을 수행하지만 정확히 어떻게하는지 시간이 걸리지 않았습니다.

메서드 매개 변수 이름과 URI 템플릿 변수 이름의 일치는 디버깅이 활성화 된 상태로 코드가 컴파일 된 경우에만 수행 할 수 있습니다. 디버깅을 활성화하지 않은 경우 변수 이름의 확인 된 값을 메서드 매개 변수에 바인딩하려면 @PathVariable 주석에 URI 템플릿 변수 이름의 이름을 지정해야합니다. 예를 들면 :

봄 문서 에서 가져옴