zoukankan      html  css  js  c++  java
  • java 反射借助 asm 获取参数名称最优雅简单的方式

    背景说明

    最近写反射相关的代码,想获取对应的参数名称,却发现没有特别好的方式。

    jdk7 及其以前,是无法通过反射获取参数名称的。

    jdk8 可以获取,但是要求指定 -parameter 启动参数,限制较多。

    期间尝试过类似于 Mybatis 使用 @Param 的方式,但是感觉不够优雅,后来发现了下面的这个工具。

    asm-tool 是基于 asm 构建的常见工具类。

    下面简单介绍下使用方式。

    快速开始

    准备

    jdk 1.7+

    maven 3.x+

    maven 引入

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

    获取方法参数名称

    测试方法

    AsmMethodsTest 类下定义一个带有参数的方法

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

    获取参数名称

    通过 AsmMethods.getParamNamesByAsm(Method) 获取参数名称。

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

    第一行获取我们定义的方法对应的 Method 信息;

    第一行直接调用获取结果;

    第三行进行断言验证。

    基于参数注解

    参数注解

    使用过 mybatis 的开发对于 @Param 注解应该并不陌生。

    其实这也是一种解决获取方法名称的方式,那就是基于 @Param 注解。

    @Param 注解

    这个注解非常简单,直接可以定义在参数列表上,用于显示指定该字段的名称。

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

    获取方式

    通过 AsmMethods.getParamNamesByAnnotation(Method) 即可获取。

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

    未指定注解的场景

    如果你没有指定注解,则会返回 arg0/arg1/... 这样的结果。

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

    获取构造器参数名称

    简介

    和获取方法非常类似。

    也有基于注解和基于 asm 两种方式。

    基于注解

    • 构造器定义
    public ConstructorService(@Param("age") Integer age) {
    }
    
    • 获取参数名称
    Constructor constructor = ClassUtil.getConstructor(ConstructorService.class, Integer.class);
    List<String> param =  AsmMethods.getParamNamesByAnnotation(constructor);
    Assert.assertEquals("[age]", param.toString());
    

    基于 asm

    • 构造器定义
    public ConstructorService(String name) {
    }
    
    • 获取参数名称
    Constructor constructor = ClassUtil.getConstructor(ConstructorService.class, String.class);
    List<String> param =  AsmMethods.getParamNamesByAsm(constructor);
    Assert.assertEquals("[name]", param.toString());
    
  • 相关阅读:
    软件工程(2019)第一次作业
    Coding.net主页地址链接
    解决Oracle 11g重建em时报错创建档案资料库时出错以及删除原有em时报监听程序未启动
    解决VirtualBox与锐捷网络冲突的问题
    王道数据结构复习(一)
    第二次结对编程—四则运算自动生成程序
    软件工程(2019)结对编程第一次作业
    软件工程(2019)第三次个人作业——求最大子段和(于VS2017下代码覆盖单元测试)
    软件工程(2019)第二次作业
    软件工程第一次作业
  • 原文地址:https://www.cnblogs.com/houbbBlogs/p/12036381.html
Copyright © 2011-2022 走看看