技术公众号:Java In Mind(Java_In_Mind),欢迎关注!

原文:Java8增强反射可以在运行时获取参数名

介绍

在JDK增强意见:JPE 118:Access to Parameter Names at Runtime中指出,在Java8中我们终于可以通过反射来获取方法的参数名,其主要的目的是:

提高代码的可读性(原先通常使用注解来实现)

可以提高IDE的功能

JDK8前获取参数名的方法

通过注解来实现

因为Java8之前不提供获取参数名称的功能,大部分实现都是通过提供注解元数据来标明参数名,这个也是目前许多框架使用的方法,如,SpringMVC的参数绑定,MyBatis的参数映射,类似:

//自定义@param注解

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Param {

String value();

}

//声明参数名

public void foo(@Param("name") String name, @Param("count") int count){

System.out.println("name:=" + name + ",count=" + count);

}

//获取

Method foo = ParameterDemo.class.getMethod("foo", String.class, int.class);

Annotation[][] parameterAnnotations = foo.getParameterAnnotations();

for (Annotation[] parameterAnnotation : parameterAnnotations) {

for (Annotation annotation : parameterAnnotation) {

if(annotation instanceof Param){

System.out.println(((Param) annotation).value());

}

}

}

//获取结果

name

count

通过解析class文件

可以通过解析二进制文件来获取参数的名称,常见的工具有:ASM,javassist,如,Spring的LocalVariableTableParameterNameDiscoverer,就是利用ASM通过class文件中的本地方法变量表中获取到参数名称:

//使用Spring的LocalVariableTableParameterNameDiscoverer获取

public void foo(String name, int count){

System.out.println("name:=" + name + ",count=" + count);

}

Method foo = ParameterDemo.class.getMethod("foo", String.class, int.class);

String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(foo);

System.out.println(Arrays.toString(parameterNames));

//获取结果

[name, count]

使用Java8反射

JDK8在反射包中新增了Parameter类,用于表示方法的参数信息,通过Method来获取所有参数列表:

public void foo(String name, int count){

System.out.println("name:=" + name + ",count=" + count);

}

//通过反射获取

Method foo = ParameterDemo.class.getMethod("foo", String.class, int.class);

Parameter[] parameters = foo.getParameters();

for (Parameter parameter : parameters) {

System.out.println(parameter.getName());

}

//获取结果

name

count

【注意】

该功能需要在javac编译时开启-parameters参数,而为了兼容性该参数默认是不开启的,如果使用Maven构建的话可以如此配置:

org.apache.maven.plugins

maven-compiler-plugin

8

8

-parameters

【原理】

通过反编译可以知道,class文件保存了MethodParameters的信息,这就是保存方法名的地方:

//截取片段

public void foo(java.lang.String, int);

descriptor: (Ljava/lang/String;I)V

flags: ACC_PUBLIC

Code:

stack=3, locals=3, args_size=3

0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

3: new #3 // class java/lang/StringBuilder

6: dup

7: invokespecial #4 // Method java/lang/StringBuilder."":()V

10: ldc #5 // String name:=

12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

15: aload_1

16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

19: ldc #7 // String ,count=

21: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

24: iload_2

25: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;

28: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

31: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

34: return

LineNumberTable:

line 14: 0

line 15: 34

LocalVariableTable:

Start Length Slot Name Signature

0 35 0 this Lcom/sevenlin/demo/reflect/ParameterDemo;

0 35 1 name Ljava/lang/String;

0 35 2 count I

MethodParameters:

Name Flags

name

count

总结

Java运行时是使用位置解析参数的,但随着应用的发展,常常需要获取参数名的功能,如一些IDE的反编译功能,由于Java8之前不支持参数名的获取,通常都是通过别的方法来实现,通常就是通过注解,这会使代码比较混乱,而且冗余,降低代码阅读性,而通过解析class文件的方式来获取比较麻烦,而且也不提倡。

Java8对反射的增加也是为了解决以上的问题,而使用的时候注意要在编译时开启。

java 获取运行时参数,Java8增强反射可以在运行时获取参数名相关推荐

  1. Java学习第五天,增强for,方法重载,可变参数,数组定义及稀疏数组。

    增强for,方法重载,可变参数,数组定义及稀疏数组. 增强for package com.hyb.base;public class for_strengthen {public static voi ...

  2. java获取注解的属性值_反射+自定义注解,实现获取注解标记的属性

    目标:通过自定义注解 @Ignore 注解,觉得是否读取指定类的属性. 运行结果: [main] INFO util.FruitInfoUtil -水果的名字为:entity.Apple [main] ...

  3. 【Java 19】反射 - 反射机制概述、获取Class实例、类的加载与ClassLoader的理解、创建运行时类的对象、获取运行时类的完整结构、调用运行时类的指定结构、动态代理

    反射机制概述.获取Class实例.类的加载与ClassLoader的理解.创建运行时类的对象.获取运行时类的完整结构.调用运行时类的指定结构.动态代理 反射 1 Java反射机制概述 1.1 Java ...

  4. java 反射调用set方法_java反射调用set方法时如果让参数做自动类型转换

    这段时间学习java的反射机制想实现一个功能:遍历一个Map,然后利用反射机制调用BO的set方法,完成BO属性的自动注入.这样设计的初衷是解决Excel数据导入问题中的Map数据填充BO这一过程. ...

  5. Java反射基础(一)--Class对象获取

    Classes Java中,任何一个对象要么是一个引用类型要么是基本数据类型.引用类型指的是那些直接或间接 Java.lang.Object的类.Classse,enum,和接口都是应用类型.基本类型 ...

  6. java 获取当前年_java中的反射(三) - kelexin

    目录一.反射1.class类2.访问字段3.调用方法4.调用构造方法5.获取继承对象6.动态代理二.sping中的反射 本篇转自:本篇内容spring中的反射 java中的反射(一): java中的反 ...

  7. java反射 enum参数_CookBook/3-Java反射.md at master · Byron4j/CookBook · GitHub

    Java核心(三)反射 Java反射给我们提供了在运行时检查甚至修改应用行为的机制. 反射是java高级的核心技术,所有有经验的程序员都应该理解. 通过反射机制,我们可以在运行时检视 类.接口.枚举, ...

  8. java 不退出_Java项目不挂断运行,即当账户退出或终端关闭时,程序仍然运行,并附上执行脚本...

    把打包好的jar包上传服务器以后,直接运行java -jar+文件名 命令即可以完成启动. 若需要在公网上如何不挂断开启程序,可以使用nohup java -jar +文件名 &命令,其中no ...

  9. java运行时异常的特点是什么_Java运行时异常和非运行时异常

    1.Java异常机制 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类.Java中的异常分为两大类:错误Error和异常Exception,Java ...

最新文章

  1. mysql-cluster 安装配置
  2. 英特尔人工智能副总裁:AI不是一种技能,而是一种对于工作的描述
  3. 对象引用未保存的瞬态实例-在刷新之前保存瞬态实例
  4. day05:SQL_DCL ,权限控制
  5. CVPR 2022 3月7日论文速递(17 篇打包下载)涵盖 3D 目标检测、医学影像、图像去模糊、车道线检测等方向
  6. 程序员开发windows linux,好程序员不用windows作开发环境
  7. 使用ISA Server保护内部的web服务器
  8. T5: Text-To-Text Transfer Transformer
  9. Atitit layout art 布局的艺术目录1. SpringLayout 类 弹簧布局管理器 12. BoxLayout( html默认布局) 11.SpringLayout
  10. 曲奇云盘资源搜索引擎_曲奇云盘下载-曲奇云盘官网版v3.2.4-sosyes
  11. python cnn 股市_荐python3绘制股票K线图的那些坑【一】mpl_finance迁向mplfinance,以及plot独立窗口视图问题!...
  12. html页面布局实验原理,Html设计实验报告.doc
  13. html网页制作比赛要求,校园网页设计大赛活动方案
  14. SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口
  15. stm32: 串口空闲中断的实现(HAL库)
  16. 爬虫抓取某饿了app商铺的评论数据
  17. 你家200兆宽带 真的就是200兆吗?原来我们一直都搞错了
  18. ubuntu 系统 耳机嘶嘶声 白噪声 修复
  19. 上班摸鱼 这个软件少不了 任意窗口透明化
  20. Android 8.0系统源码分析--Camera processCaptureResult结果回传源码分析

热门文章

  1. 微博转发的内容如何实现点击人名跳转到个人主页
  2. web app 自适应方案总结 弹性布局之rem
  3. IE6下Png透明最佳解决方案(推荐) Unit PNG Fix
  4. 防御暴力破解SSH攻击
  5. 当使用malloc提示找不到标识符时?
  6. javaScript对象及初识面向对象
  7. 19、SOAP安装,运用与比对结果解释
  8. 七种实现左侧固定,右侧自适应两栏布局的方法
  9. HDU2216:Game III(BFS)
  10. Linux脚本Shell命令