• 【反射】Method类


    Method类中包含了方法定义的详细信息,可以使用Method类中提供的方法来获取方法的信息,下面我们先获取Method对象,再介绍如何使用Method类中提供的方法。

    一、准备工作

    在src/test/java目录的cn.horse.reflect.entity包下新建BaseEntity类、UserInfoEntity类;新建EntityAnnotation、InheritedEntityAnnotation、UserInfoEntityAnnotation注解

    BaseEntity类:

    1. package cn.horse.reflect.entity;
    2. @EntityAnnotation
    3. @InheritedEntityAnnotation
    4. public abstract class BaseEntity {
    5. @EntityAnnotation
    6. @InheritedEntityAnnotation
    7. public Long id;
    8. @InheritedEntityAnnotation
    9. public BaseEntity() { }
    10. @EntityAnnotation
    11. @InheritedEntityAnnotation
    12. public BaseEntity(Long id) {
    13. this.id = id;
    14. }
    15. @EntityAnnotation
    16. @InheritedEntityAnnotation
    17. public void setId(Long id) {
    18. this.id = id;
    19. }
    20. public Long getId() {
    21. return id;
    22. }
    23. }

    UserInfoEntity类:

    1. package cn.horse.reflect.entity;
    2. @UserInfoEntityAnnotation
    3. public class UserInfoEntity extends BaseEntity {
    4. @UserInfoEntityAnnotation
    5. public String name;
    6. @UserInfoEntityAnnotation
    7. private Integer age;
    8. @UserInfoEntityAnnotation
    9. private UserInfoEntity() {
    10. }
    11. @UserInfoEntityAnnotation
    12. public UserInfoEntity(Long id) {
    13. super(id);
    14. }
    15. @UserInfoEntityAnnotation
    16. public UserInfoEntity(Long id, String name, Integer age) {
    17. super(id);
    18. this.name = name;
    19. this.age = age;
    20. }
    21. public void setAge(Integer age) {
    22. this.age = age;
    23. }
    24. public Integer getAge() {
    25. return age;
    26. }
    27. private String getName() {
    28. return name;
    29. }
    30. private void check() { }
    31. @UserInfoEntityAnnotation
    32. @Override
    33. public void setId(Long id) {
    34. super.setId(id);
    35. }
    36. }

    EntityAnnotation注解:

    1. package cn.horse.reflect.entity;
    2. import java.lang.annotation.Retention;
    3. import java.lang.annotation.RetentionPolicy;
    4. import java.lang.annotation.Target;
    5. import static java.lang.annotation.ElementType.*;
    6. @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    7. @Retention(RetentionPolicy.RUNTIME)
    8. public @interface EntityAnnotation {
    9. }

    InheritedEntityAnnotation注解:

    1. package cn.horse.reflect.entity;
    2. import java.lang.annotation.Inherited;
    3. import java.lang.annotation.Retention;
    4. import java.lang.annotation.RetentionPolicy;
    5. import java.lang.annotation.Target;
    6. import static java.lang.annotation.ElementType.*;
    7. import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
    8. @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    9. @Retention(RetentionPolicy.RUNTIME)
    10. @Inherited
    11. public @interface InheritedEntityAnnotation {
    12. }

    UserInfoEntityAnnotation注解:

    1. package cn.horse.reflect.entity;
    2. import java.lang.annotation.Retention;
    3. import java.lang.annotation.RetentionPolicy;
    4. import java.lang.annotation.Target;
    5. import static java.lang.annotation.ElementType.*;
    6. import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
    7. @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
    8. @Retention(RetentionPolicy.RUNTIME)
    9. public @interface UserInfoEntityAnnotation {
    10. }

    二、获取Method对象

    在src/test/java目录的cn.horse.reflect包下新建GetMethodInstanceTests测试类

    GetMethodInstanceTests类:

    1. package cn.horse.reflect;
    2. import cn.horse.reflect.entity.UserInfoEntity;
    3. import org.junit.jupiter.api.Test;
    4. import java.lang.reflect.Method;
    5. import java.util.Arrays;
    6. import java.util.Collection;
    7. import java.util.List;
    8. import java.util.stream.Collectors;
    9. import static org.assertj.core.api.Assertions.assertThat;
    10. import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
    11. public class GetMethodInstanceTests {
    12. static final Class USER_INFO_ENTITY_CLASS = UserInfoEntity.class;
    13. @Test
    14. public void testGetMethods() {
    15. // getMethods 获取当前类及其父类中使用public定义的方法
    16. Collection methodNameList = Arrays.stream(USER_INFO_ENTITY_CLASS.getMethods()).map(Method::getName).collect(Collectors.toSet());
    17. List expectedMethodNameList = Arrays.asList("getAge", "setAge", "getId", "setId", "getClass", "hashCode", "equals", "toString", "notify", "notifyAll", "wait");
    18. assertThat(methodNameList.size()).isEqualTo(expectedMethodNameList.size());
    19. assertThat(methodNameList).containsAll(expectedMethodNameList);
    20. }
    21. @Test
    22. public void testGetMethod() throws NoSuchMethodException {
    23. UserInfoEntity userInfoEntity = new UserInfoEntity(200L, "张三", 10);
    24. assertThat(USER_INFO_ENTITY_CLASS.getMethod("getId")).isNotNull();
    25. assertThatExceptionOfType(NoSuchMethodException.class).isThrownBy(() -> { USER_INFO_ENTITY_CLASS.getMethod("getName"); });
    26. assertThat(USER_INFO_ENTITY_CLASS.getMethod("getAge")).isNotNull();
    27. }
    28. @Test
    29. public void testGetDeclaredMethods() {
    30. // getDeclaredMethods 获取当前类中定义的所有方法(不能获取父类中定义的方法)
    31. Collection declaredMethodNameList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredMethods()).map(Method::getName).collect(Collectors.toSet());
    32. List expectedDeclaredMethodNameList = Arrays.asList("setAge", "getAge", "setId", "getName", "check");
    33. assertThat(declaredMethodNameList.size()).isEqualTo(expectedDeclaredMethodNameList.size());
    34. assertThat(declaredMethodNameList).containsAll(expectedDeclaredMethodNameList);
    35. }
    36. @Test
    37. public void testGetDeclaredMethod() throws NoSuchMethodException {
    38. UserInfoEntity userInfoEntity = new UserInfoEntity(200L, "张三", 10);
    39. assertThatExceptionOfType(NoSuchMethodException.class).isThrownBy(() -> { USER_INFO_ENTITY_CLASS.getDeclaredMethod("getId"); });
    40. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getName")).isNotNull();
    41. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getAge")).isNotNull();
    42. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("check")).isNotNull();
    43. }
    44. }

    单元测试方法介绍:

    testGetMethods使用getMethods方法获取当前类及其父类中使用public定义的所有字段

    testGetMethod使用getMethod方法获取当前类及其父类中使用public定义的指定字段

    testGetDeclaredMethods使用getDeclaredMethods方法获取当前类中定义的所有字段

    testGetDeclaredMethod使用getDeclaredMethod方法获取当前类中定义的指定字段

    三、Method类中方法的使用

    在src/test/java目录的cn.horse.reflect包下新建MethodInstanceMethodTests测试类

    MethodInstanceMethodTests类:

    1. package cn.horse.reflect;
    2. import cn.horse.reflect.entity.*;
    3. import org.junit.jupiter.api.Test;
    4. import java.lang.annotation.Annotation;
    5. import java.lang.reflect.InvocationTargetException;
    6. import java.lang.reflect.Method;
    7. import java.lang.reflect.Modifier;
    8. import java.util.Arrays;
    9. import java.util.Collection;
    10. import java.util.List;
    11. import java.util.stream.Collectors;
    12. import static org.assertj.core.api.Assertions.assertThat;
    13. import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
    14. public class MethodInstanceMethodTests {
    15. static final Class USER_INFO_ENTITY_CLASS = UserInfoEntity.class;
    16. @Test
    17. public void testGetDeclaringClass() throws NoSuchMethodException {
    18. assertThat(USER_INFO_ENTITY_CLASS.getMethod("getId").getDeclaringClass()).isEqualTo(BaseEntity.class);
    19. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getName").getDeclaringClass()).isEqualTo(UserInfoEntity.class);
    20. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getAge").getDeclaringClass()).isEqualTo(UserInfoEntity.class);
    21. }
    22. @Test
    23. public void testGetReturnType() throws NoSuchMethodException {
    24. assertThat(USER_INFO_ENTITY_CLASS.getMethod("getId").getReturnType()).isEqualTo(Long.class);
    25. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getName").getReturnType()).isEqualTo(String.class);
    26. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getAge").getReturnType()).isEqualTo(Integer.class);
    27. }
    28. @Test
    29. public void testGetName() throws NoSuchMethodException {
    30. assertThat(USER_INFO_ENTITY_CLASS.getMethod("getId").getName()).isEqualTo("getId");
    31. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getName").getName()).isEqualTo("getName");
    32. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getAge").getName()).isEqualTo("getAge");
    33. }
    34. @Test
    35. public void testGetModifiers() throws NoSuchMethodException {
    36. assertThat(Modifier.isPublic(USER_INFO_ENTITY_CLASS.getMethod("getId").getModifiers())).isTrue();
    37. assertThat(Modifier.isPrivate(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getName").getModifiers())).isTrue();
    38. assertThat(Modifier.isPublic(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getAge").getModifiers())).isTrue();
    39. }
    40. @Test
    41. public void testInvokeMethodGetValue() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    42. UserInfoEntity userInfoEntity = new UserInfoEntity(200L, "张三", 10);
    43. assertThat(USER_INFO_ENTITY_CLASS.getMethod("getId").invoke(userInfoEntity)).isEqualTo(200L);
    44. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("getAge").invoke(userInfoEntity)).isEqualTo(10);
    45. // 获取getName方法
    46. Method nameMethod = USER_INFO_ENTITY_CLASS.getDeclaredMethod("getName");
    47. assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() -> { nameMethod.invoke(userInfoEntity); });
    48. nameMethod.setAccessible(true);
    49. assertThat(nameMethod.invoke(userInfoEntity)).isEqualTo("张三");
    50. }
    51. @Test
    52. public void testInvokeMethodSetValue() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    53. UserInfoEntity userInfoEntity = new UserInfoEntity(200L, "张三", 10);
    54. USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).invoke(userInfoEntity, 300L);
    55. USER_INFO_ENTITY_CLASS.getDeclaredMethod("setAge", Integer.class).invoke(userInfoEntity, 20);
    56. assertThat(userInfoEntity.getId()).isEqualTo(300L);
    57. assertThat(userInfoEntity.name).isEqualTo("张三");
    58. assertThat(userInfoEntity.getAge()).isEqualTo(20);
    59. }
    60. @Test
    61. public void testGetAnnotations() throws NoSuchMethodException {
    62. Collectionextends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getAnnotations()).map(Annotation::annotationType).collect(Collectors.toList());
    63. Listextends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class);
    64. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    65. assertThat(annotationList).containsAll(expectedAnnotationList);
    66. }
    67. @Test
    68. public void testGetAnnotationsByType() throws NoSuchMethodException {
    69. Collectionextends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getAnnotationsByType(UserInfoEntityAnnotation.class)).map(Annotation::annotationType).collect(Collectors.toList());
    70. Listextends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class);
    71. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    72. assertThat(annotationList).containsAll(expectedAnnotationList);
    73. }
    74. @Test
    75. public void testGetAnnotation() throws NoSuchMethodException {
    76. assertThat(USER_INFO_ENTITY_CLASS.getMethod("setId", Long.class).getAnnotation(EntityAnnotation.class)).isNull();
    77. assertThat(USER_INFO_ENTITY_CLASS.getMethod("setId", Long.class).getAnnotation(InheritedEntityAnnotation.class)).isNull();
    78. assertThat(USER_INFO_ENTITY_CLASS.getMethod("setId", Long.class).getAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
    79. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getAnnotation(EntityAnnotation.class)).isNull();
    80. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getAnnotation(InheritedEntityAnnotation.class)).isNull();
    81. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
    82. }
    83. @Test
    84. public void testGetDeclaredAnnotations() throws NoSuchMethodException {
    85. Collectionextends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getDeclaredAnnotations()).map(Annotation::annotationType).collect(Collectors.toList());
    86. Listextends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class);
    87. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    88. assertThat(annotationList).containsAll(expectedAnnotationList);
    89. }
    90. @Test
    91. public void testGetDeclaredAnnotationsByType() throws NoSuchMethodException {
    92. Collectionextends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getDeclaredAnnotationsByType(UserInfoEntityAnnotation.class)).map(Annotation::annotationType).collect(Collectors.toList());
    93. Listextends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class);
    94. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    95. assertThat(annotationList).containsAll(expectedAnnotationList);
    96. }
    97. @Test
    98. public void testGetDeclaredAnnotation() throws NoSuchMethodException {
    99. assertThat(USER_INFO_ENTITY_CLASS.getMethod("setId", Long.class).getDeclaredAnnotation(EntityAnnotation.class)).isNull();
    100. assertThat(USER_INFO_ENTITY_CLASS.getMethod("setId", Long.class).getDeclaredAnnotation(InheritedEntityAnnotation.class)).isNull();
    101. assertThat(USER_INFO_ENTITY_CLASS.getMethod("setId", Long.class).getDeclaredAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
    102. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getDeclaredAnnotation(EntityAnnotation.class)).isNull();
    103. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getDeclaredAnnotation(InheritedEntityAnnotation.class)).isNull();
    104. assertThat(USER_INFO_ENTITY_CLASS.getDeclaredMethod("setId", Long.class).getDeclaredAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
    105. }
    106. }

    单元测试方法介绍:

    testGetDeclaringClass使用getDeclaringClass方法获取到方法所在类(声明类)的Class对象

    testGetReturnType使用getReturnType方法获取方法的返回值类型

    testGetName使用getName方法获取方法的名称

    testGetModifiers使用getModifiers获取修饰符,并使用Modifier类提供的静态方法依次判断了是否使用了public、private、protected等修饰符

    testInvokeMethodGetValue使用invoke方法调用方法,如果方法不可访问会抛出IllegalAccessException异常,使用setAccessible方法可以控制访问权限。

    testInvokeMethodSetValue使用invoke方法调用方法,如果方法不可访问会抛出IllegalAccessException异常,使用setAccessible方法可以控制访问权限。

    testGetAnnotations使用getAnnotations获取方法的所有注解

    testGetAnnotationsByType使用getAnnotationsByType从方法的注解中获取指定类型的注解

    testGetAnnotation使用getAnnotation从方法的注解中获取指定类型的注解

    testGetDeclaredAnnotations使用getDeclaredAnnotations获取方法的所有注解

    testGetDeclaredAnnotationsByType使用getDeclaredAnnotationsByType从方法的注解中获取指定类型的注解

    testGetDeclaredAnnotation使用getDeclaredAnnotation从方法的注解中获取指定类型的注解

  • 相关阅读:
    Linux下基本指令,ls,pwd,cd 等等(持续更新中)
    PHP没死,依然有78%的网站在使用
    Linux 服务器(Ubuntu) 安装 golang记录
    vivado时序分析-1
    如何选择合适的自动化测试工具?
    .Net服务器性能监控,应用耗时统一监控平台
    揭秘源代码加密方案,完美支持Jenkins代码自动化部署发布
    windows平台FairMOT的实现
    c++代码区域折叠
    ERP 技术列表
  • 原文地址:https://blog.csdn.net/m1729339749/article/details/134068979