原文链接: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类常用方法解析相关推荐

  1. Class -- 10 -- Method类常用方法解析

    原文链接:Class – 10 – Method类常用方法解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – ...

  2. Class -- 09 -- Field类常用方法解析

    原文链接:Class – 09 – Field类常用方法解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – 0 ...

  3. Class -- 03 -- Random类常用方法详解析

    原文链接:Class – 03 – Random类常用方法详解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – ...

  4. Java常用类全面解析(含部分源码)

    常用类 文章目录 常用类 字符串相关的类 String 类 说明 案例 String 的实例方式 String 中的常用方法 案例一 案例二 案例三 String 类与其它结构之间的转换 小复习-与基 ...

  5. Java实用类,包装类,日历类,日期类等工具类常用方法

    文章目录 第二章-实用类 1.枚举类型 2.包装类 3.包装类的常用方法 4.包装类的自动装箱和拆箱 5.String类 6.StringBuffer对象 String,StringBuffer,St ...

  6. Java基础-Date类常用方法介绍

    Java基础-Date类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.毫秒值概念 我们在查阅Date类的API文档时,会发现这样的一句话:"The cl ...

  7. es6删除数组某一项_javascript基础系列:数组常用方法解析

    javascript基础系列:数组常用方法解析 今天是比较特殊的日子,我们编程人员共同的节日,1024,祝每个编程人员节日快乐! 数组是javascript必不可少的一项,今天让我们来总结一下数组操作 ...

  8. 面试官系统精讲Java源码及大厂真题 - 08 HashMap 源码解析

    08 HashMap 源码解析 自信和希望是青年的特权. --大仲马 引导语 HashMap 源码很长,面试的问题也非常多,但这些面试问题,基本都是从源码中衍生出来的,所以我们只需要弄清楚其底层实现原 ...

  9. javascript基础系列:数组常用方法解析

    javascript基础系列:数组常用方法解析 今天是比较特殊的日子,我们编程人员共同的节日,1024,祝每个编程人员节日快乐! 数组是javascript必不可少的一项,今天让我们来总结一下数组操作 ...

最新文章

  1. 多快好省的宏基因组研究技巧 — 资深专家分享
  2. python学生管理系统-Python 学生信息管理系统 2.0
  3. ios android 录音格式,跨系统的录音格式兼容性问题: iOS Android
  4. 服务器系统自带虚拟机吗,现在所说的服务器虚拟化,也就是在vmware虚拟机上搭建的吗...
  5. plsql(轻量版)_流程控制
  6. 数字转字符函数_Excel之文本函数CONCATENATE/TEXT/LEFT/MID/RIGHT/FIND/LEN
  7. 【redis系列】redisTemplate缓存常用工具类
  8. centos 6.8 升级mysql_centos6.8 Mysql5.6.22 升级 mysql-5.7.20
  9. JDK6和JDK7中String的substring()方法及其差异
  10. url相关工具 - url转码工具
  11. Android相机对焦问题
  12. 玩转Linux的下Ip计算器(图文)
  13. TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:1~5
  14. STC15系列单片机与 OV7670 SCCB通讯
  15. W25Q64Flash芯片STM32操作
  16. Python爬取动态网页实例讲解
  17. 备份恢复 --已整理
  18. pytorch从hdfs载入模型、从二进制字符串载入模型
  19. FL2440(S3C2440A 芯片) 开发板开发笔记
  20. Linux 命令缩写及参数

热门文章

  1. 【亲测有效】mac电脑也能玩魔兽世界怀旧版(wow经典怀旧版)
  2. 原来陈寿福进去了~~~
  3. K12526 找双亲和孩子
  4. LabVIEW(十五):右键菜单添加创建VI模版
  5. GBase 8a 核心服务组件功能简介
  6. Linux系统进阶-基础IO
  7. 天猫用户重复购买预测之数据分析
  8. 百度关于EMP的探索:落地生产可用的微前端架构
  9. error: No rule to make target '/usr/lib/libOpenNI.so', needed by 'bin/euroc_rectify'。 停止。
  10. 百度产品战略的变化历程