The most elegant and simple way for java reflection to get parameter names with asm

Keywords: Java Mybatis Maven JDK github

Background description

Recently, I wrote reflection-related code and wanted to get the name of the corresponding parameter, but found there was no particularly good way.

jdk7 and before was not able to get parameter names through reflection.

jdk8 is available, but there are many restrictions on specifying the-parameter startup parameter.

I tried something similar to the way Mybatis uses @Param, but it didn't feel elegant enough, and later discovered the tool below.

asm-tool Common tool classes built on asm.

Here is a brief description of how to use it.

Quick Start

Get ready

jdk 1.7+

maven 3.x+

Introduction of maven

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>asm-tool</artifactId>
    <version>0.0.2</version>
</dependency>

Get method parameter name

test method

Define a method with parameters under the AsmMethodsTest class

public String common(String name) {
    return name;
}

Get parameter name

Get the parameter name from AsmMethods.getParamNamesByAsm(Method).

Method method = ClassUtil.getMethod(AsmMethodsTest.class,
        "common", String.class);
List<String> param =  AsmMethods.getParamNamesByAsm(method);
Assert.assertEquals("[name]", param.toString());

The first line gets the Method information for the method we defined.

The first line calls directly to get the result;

The third line validates the assertion.

Parameter-based annotations

Parametric Note

Developing with mybatis should not be unfamiliar with the @Param annotation.

This is also a way to get the method name based on the @Param annotation.

@Param comment

This annotation is very simple and can be defined directly on the parameter list to display the name of the specified field.

public String forParam(@Param("name") String name) {
    return name;
}

Getting Method

This is available through AsmMethods.getParamNamesByAnnotation(Method).

Method method = ClassUtil.getMethod(AsmMethodsTest.class,
        "forParam", String.class);
List<String> param =  AsmMethods.getParamNamesByAnnotation(method);
Assert.assertEquals("[name]", param.toString());

Scenarios with no notes specified

If you do not specify a comment, the result will be arg0/arg1/....

Method method = ClassUtil.getMethod(AsmMethodsTest.class,
        "common", String.class);
List<String> param =  AsmMethods.getParamNamesByAnnotation(method);
Assert.assertEquals("[arg0]", param.toString());

Get the constructor parameter name

brief introduction

It's very similar to the get method.

There are also annotation-based and asm-based approaches.

annotation-based

  • Constructor Definition
public ConstructorService(@Param("age") Integer age) {
}
  • Get parameter name
Constructor constructor = ClassUtil.getConstructor(ConstructorService.class, Integer.class);
List<String> param =  AsmMethods.getParamNamesByAnnotation(constructor);
Assert.assertEquals("[age]", param.toString());

Based on asm

  • Constructor Definition
public ConstructorService(String name) {
}
  • Get parameter name
Constructor constructor = ClassUtil.getConstructor(ConstructorService.class, String.class);
List<String> param =  AsmMethods.getParamNamesByAsm(constructor);
Assert.assertEquals("[name]", param.toString());

Posted by salmanshafiq on Sat, 14 Dec 2019 01:13:44 -0800