Class -- 08 -- Parameter类常用方法解析
原文链接:Class – 08 – Parameter类常用方法解析
相关文章:
Class – 01 – System类常用方法解析
Class – 02 – Arrays类常用方法解析
Class – 03 – Random类常用方法详解析
Class – 04 – Date类常用方法解析
Class – 05 – TimeUnit类常用方法解析
Class – 06 – TimeZone类常用方法详解析
Class – 07 – Modifier类常用方法解析
Class – 08 – Parameter类常用方法解析
Class – 09 – Field类常用方法解析
Class – 10 – Method类常用方法解析
Class – 11 – Math类常用方法解析
Class – 12 – Locale类常用方法解析
Class – 13 – ThreadPoolExecutor类常用方法解析
这次主要整理下 Java 中 Parameter 类的常用方法
一、Parameter 类的定义
Parameter 类位于 java.lang.reflect 包中,主要用于在程序运行状态中,动态地获取参数信息
在 JDK8.0 之前,编译器会忽略我们编写代码时设定的参数名,因此会得到像 arg0、arg1 这样无意义的参数名,比如:当我们使用 mybatis 时,我们会用到 @Param 注解来使 mybatis 保留参数名称
在 JDK8.0 及之后,Java 在语言层面 (使用反射 API 和 Parameter.getName() 方法) 和字节码层面 (使用新的 javac 编译器以及 -parameters 参数) 提供了支持,不过为了保证向下兼容,在 JDK8.0 及之后的版本中该特性是默认关闭的
在 IDEA 中我们可以通过以下设置来完成
如果使用了 maven,可以配置 maven 的编译插件
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version><configuration><compilerArgument>-parameters</compilerArgument><source>1.8</source><target>1.8</target></configuration> </plugin>
示例如下
public class ParameterTest {public void test(String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {// 正常编译得到: arg0 arg1// 加入-parameters后编译得到: key valueSystem.out.println(parameter.getName());}} }
二、Parameter 类常用方法
getAnnotatedType()
返回一个 AnnotatedType 对象,该对象表示使用类型来指定由该参数对象表示的形式参数的类型
通过其 getType() 方法,我们可以获取到对应的形参类型
public class ParameterTest {public void test(String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {AnnotatedType annotatedType = parameter.getAnnotatedType();// class java.lang.String// class java.lang.StringSystem.out.println(annotatedType.getType());}} }
getAnnotation(Class<T> annotationClass)
如果该参数对象存在指定类型的注解,则返回该注解,否则返回 null
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface ParameterAnnotation {String key();String value(); }public class ParameterTest {public void test(@ParameterAnnotation(key = "key", value = "value") String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();ParameterAnnotation annotation = parameters[0].getAnnotation(ParameterAnnotation.class);// @lang.reflect.Parameter.ParameterAnnotation(key=key, value=value)System.out.println(annotation);} }
getDeclaredAnnotation(Class<T> annotationClass)
如果该参数对象存在指定类型的注解,则返回该注解,否则返回 null
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同
getAnnotationsByType(Class<T> annotationClass)
如果该参数对象存在指定类型的注解,则返回该注解数组,否则返回 null
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同
getAnnotationsByType() 方法与 getAnnotation() 方法的区别在于:getAnnotationsByType() 方法会检查修饰该参数对象的注解是否为可重复类型注解,如果是则会返回修饰该参数对象的一个或多个注解
@Repeatable 用于声明注解为可重复类型注解
当声明为可重复类型注解后,如果参数注解仍为一个,则 getAnnotation() 方法会正常返回,如果参数注解为多个,则 getAnnotation() 方法会返回 null
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) // @Repeatable: 声明该注解为可重复类型注解 @Repeatable(RepeatableAnnotation.class) public @interface ParameterAnnotation {String key();String value(); }@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @interface RepeatableAnnotation {ParameterAnnotation[] value(); }public class ParameterTest {public void test(@ParameterAnnotation(key = "key1", value = "value1")@ParameterAnnotation(key = "key2", value = "value2") String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();ParameterAnnotation annotation = parameters[0].getAnnotation(ParameterAnnotation.class);// nullSystem.out.println(parameters[0].getAnnotation(ParameterAnnotation.class));ParameterAnnotation[] annotationsByType = parameters[0].getAnnotationsByType(ParameterAnnotation.class);// [@lang.reflect.ParameterAnnotation(key=key1, value=value1), @lang.reflect.ParameterAnnotation(key=key2, value=value2)]System.out.println(Arrays.toString(annotationsByType));} }
getDeclaredAnnotationsByType(Class<T> annotationClass)
如果该参数对象存在指定类型的注解,则返回该注解数组,否则返回null
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同
getAnnotations()
返回该参数对象上的所有注解,如果没有注解,则返回空数组
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotations() 方法与 getDeclaredAnnotations() 方法作用相同
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface ParameterAnnotation {String key();String value(); }@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation {String key();String value(); }public class ParameterTest {public void test(@ParameterAnnotation(key = "key1", value = "value1")@TestAnnotation(key = "key2", value = "value2") String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();Annotation[] annotations = parameters[0].getAnnotations();// [@lang.reflect.ParameterAnnotation(key=key1, value=value1), @lang.reflect.TestAnnotation(key=key2, value=value2)]System.out.println(Arrays.toString(annotations));} }
getDeclaredAnnotations()
返回该参数对象上的所有注解,如果没有注解,则返回空数组
只有类级别的注解会被继承得到,对于其他对象而言,getAnnotations() 方法与 getDeclaredAnnotations() 方法作用相同
getModifiers()
返回修饰该参数对象修饰符的整数形式,使用 Modifier 类对其进行解码
public class ParameterTest {public void test(final String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();// finalSystem.out.println(Modifier.toString(parameters[0].getModifiers()));} }
getName()
返回参数对象名称
public class ParameterTest {public void test(String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {// 正常编译得到: arg0 arg1// 加入-parameters后编译得到: key valueSystem.out.println(parameter.getName());}} }
getParameterizedType()
返回一个类型对象,该对象表示该参数对象表示的泛型参数的类型 (保留泛型)
public class ParameterTest<T> {public void test(T t, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", Object.class, String.class);Parameter[] parameters = method.getParameters();// TSystem.out.println(parameters[0].getParameterizedType().getTypeName());} }
getType()
返回一个 Class 对象,该 Class 对象表示该参数对象表示的声明参数的类型 (擦除泛型)
public class ParameterTest<T> {public void test(T t, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", Object.class, String.class);Parameter[] parameters = method.getParameters();// class java.lang.ObjectSystem.out.println(parameters[0].getType());} }
isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果该参数对象上有指定类型的注解,则返回 true,否则为 false
public class ParameterTest {public void test(@ParameterAnnotation(key = "key", value = "value") String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();// trueSystem.out.println(parameters[0].isAnnotationPresent(ParameterAnnotation.class));} }
如果该参数对象上的注解类型为可重复类型注解,则需要标明可重复注解而不是其子注解,才会返回 true,否则为 false
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Repeatable(RepeatableAnnotation.class) public @interface ParameterAnnotation {String key();String value(); }@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @interface RepeatableAnnotation {ParameterAnnotation[] value(); }public class ParameterTest {public void test(@ParameterAnnotation(key = "key1", value = "value1")@ParameterAnnotation(key = "key2", value = "value2") final String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();// falseSystem.out.println(parameters[0].isAnnotationPresent(ParameterAnnotation.class));// trueSystem.out.println(parameters[0].isAnnotationPresent(RepeatableAnnotation.class));} }
isVarArgs()
如果该参数对象表示 可变参,则返回 true,否则为 false
public class ParameterTest {public void test(String key, String ... values) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String[].class);Parameter[] parameters = method.getParameters();// falseSystem.out.println(parameters[0].isVarArgs());// trueSystem.out.println(parameters[1].isVarArgs());} }
isNamePresent()
如果该参数对象根据类文件能获取到名称,则返回 true,否则为 false
当我们带上 -parameters 参数时,该参数对象就有了名称
public class ParameterTest {public void test(String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();// 正常编译得到: false arg0// 加入-parameters 后编译得到: true keySystem.out.println(parameters[0].isNamePresent() + " " + parameters[0].getName());} }
getDeclaringExecutable()
返回声明该参数对象的可执行文件
public class ParameterTest {public void test(String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();// public void lang.reflect.ParameterTest.test(java.lang.String,java.lang.String)System.out.println(parameters[0].getDeclaringExecutable());} }
isImplicit()
如果该参数对象为隐式参数,则返回 true,否则为 false
Java 编译器会为内部类的构造方法创建一个隐式参数
public class ParameterTest {class InnerClass {public InnerClass(String key) {}}public static void main(String[] args) throws Exception {Constructor<InnerClass> declaredConstructor = InnerClass.class.getConstructor(ParameterTest.class, String.class);Parameter[] parameters = declaredConstructor.getParameters();for (Parameter parameter : parameters) {// 【final lang.reflect.ParameterTest this$0】 isImplicit() ===> true// 【java.lang.String key】 isImplicit() ===> falseSystem.out.println("【" + parameter + "】 isImplicit() ===> " + parameter.isImplicit());}} }
isSynthetic()
如果该参数对象为合成参数,则返回 true,否则为 false
public class ParameterTest {public void test(String key, String value) {}public static void main(String[] args) throws Exception {Method method = ParameterTest.class.getMethod("test", String.class, String.class);Parameter[] parameters = method.getParameters();// falseSystem.out.println(parameters[0].isSynthetic());} }
Class -- 08 -- Parameter类常用方法解析相关推荐
- Class -- 10 -- Method类常用方法解析
原文链接:Class – 10 – Method类常用方法解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – ...
- Class -- 09 -- Field类常用方法解析
原文链接:Class – 09 – Field类常用方法解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – 0 ...
- Class -- 03 -- Random类常用方法详解析
原文链接:Class – 03 – Random类常用方法详解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – ...
- Java常用类全面解析(含部分源码)
常用类 文章目录 常用类 字符串相关的类 String 类 说明 案例 String 的实例方式 String 中的常用方法 案例一 案例二 案例三 String 类与其它结构之间的转换 小复习-与基 ...
- Java实用类,包装类,日历类,日期类等工具类常用方法
文章目录 第二章-实用类 1.枚举类型 2.包装类 3.包装类的常用方法 4.包装类的自动装箱和拆箱 5.String类 6.StringBuffer对象 String,StringBuffer,St ...
- Java基础-Date类常用方法介绍
Java基础-Date类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.毫秒值概念 我们在查阅Date类的API文档时,会发现这样的一句话:"The cl ...
- es6删除数组某一项_javascript基础系列:数组常用方法解析
javascript基础系列:数组常用方法解析 今天是比较特殊的日子,我们编程人员共同的节日,1024,祝每个编程人员节日快乐! 数组是javascript必不可少的一项,今天让我们来总结一下数组操作 ...
- 面试官系统精讲Java源码及大厂真题 - 08 HashMap 源码解析
08 HashMap 源码解析 自信和希望是青年的特权. --大仲马 引导语 HashMap 源码很长,面试的问题也非常多,但这些面试问题,基本都是从源码中衍生出来的,所以我们只需要弄清楚其底层实现原 ...
- javascript基础系列:数组常用方法解析
javascript基础系列:数组常用方法解析 今天是比较特殊的日子,我们编程人员共同的节日,1024,祝每个编程人员节日快乐! 数组是javascript必不可少的一项,今天让我们来总结一下数组操作 ...
最新文章
- 多快好省的宏基因组研究技巧 — 资深专家分享
- python学生管理系统-Python 学生信息管理系统 2.0
- ios android 录音格式,跨系统的录音格式兼容性问题: iOS Android
- 服务器系统自带虚拟机吗,现在所说的服务器虚拟化,也就是在vmware虚拟机上搭建的吗...
- plsql(轻量版)_流程控制
- 数字转字符函数_Excel之文本函数CONCATENATE/TEXT/LEFT/MID/RIGHT/FIND/LEN
- 【redis系列】redisTemplate缓存常用工具类
- centos 6.8 升级mysql_centos6.8 Mysql5.6.22 升级 mysql-5.7.20
- JDK6和JDK7中String的substring()方法及其差异
- url相关工具 - url转码工具
- Android相机对焦问题
- 玩转Linux的下Ip计算器(图文)
- TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:1~5
- STC15系列单片机与 OV7670 SCCB通讯
- W25Q64Flash芯片STM32操作
- Python爬取动态网页实例讲解
- 备份恢复 --已整理
- pytorch从hdfs载入模型、从二进制字符串载入模型
- FL2440(S3C2440A 芯片) 开发板开发笔记
- Linux 命令缩写及参数
热门文章
- 【亲测有效】mac电脑也能玩魔兽世界怀旧版(wow经典怀旧版)
- 原来陈寿福进去了~~~
- K12526 找双亲和孩子
- LabVIEW(十五):右键菜单添加创建VI模版
- GBase 8a 核心服务组件功能简介
- Linux系统进阶-基础IO
- 天猫用户重复购买预测之数据分析
- 百度关于EMP的探索:落地生产可用的微前端架构
- error: No rule to make target '/usr/lib/libOpenNI.so', needed by 'bin/euroc_rectify'。 停止。
- 百度产品战略的变化历程