• 【反射】Class类


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

    一、准备工作

    在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. }

    二、获取Class对象的三种方式

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

    GetClassInstanceTests类:

    1. package cn.horse.reflect;
    2. import cn.horse.reflect.entity.UserInfoEntity;
    3. import org.junit.jupiter.api.Test;
    4. import static org.assertj.core.api.Assertions.assertThat;
    5. public class GetClassInstanceTests {
    6. @Test
    7. public void testGetClassInstanceByBusObjectInstance() {
    8. assertThat(new UserInfoEntity(1L).getClass()).isNotNull();
    9. }
    10. @Test
    11. public void testGetClassInstanceByBusClass() {
    12. assertThat(UserInfoEntity.class).isNotNull();
    13. }
    14. @Test
    15. public void testGetClassInstanceByName() throws ClassNotFoundException {
    16. assertThat(Class.forName("cn.horse.reflect.entity.UserInfoEntity", false, this.getClass().getClassLoader())).isNotNull();
    17. }
    18. @Test
    19. public void testClassInstanceEquals() throws ClassNotFoundException {
    20. Class forNameType = Class.forName("cn.horse.reflect.entity.UserInfoEntity", false, this.getClass().getClassLoader());
    21. Class dotClassType = UserInfoEntity.class;
    22. Class objectGetClassType = new UserInfoEntity(1L).getClass();
    23. assertThat(forNameType).isEqualTo(dotClassType);
    24. assertThat(dotClassType).isEqualTo(objectGetClassType);
    25. assertThat(forNameType).isEqualTo(objectGetClassType);
    26. }
    27. }

    单元测试方法介绍:

    testGetClassInstanceByBusObjectInstance使用对象的实例获取Class对象

    testGetClassInstanceByBusClass使用类获取Class对象

    testGetClassInstanceByName使用全限类名获取Class对象

    testClassInstanceEquals判断三种方法获取到的Class对象是否相等

    单元测试中使用了三种方式获取Class对象,三种方式获取到的Class对象是相等的。

    三、Class类中方法的使用

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

    ClassInstanceMethodTests类:

    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.Modifier;
    6. import java.util.Arrays;
    7. import java.util.Collection;
    8. import java.util.List;
    9. import java.util.Locale;
    10. import java.util.stream.Collectors;
    11. import static org.assertj.core.api.Assertions.assertThat;
    12. import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
    13. public class ClassInstanceMethodTests {
    14. @Test
    15. public void testGetName() {
    16. assertThat(UserInfoEntity.class.getSimpleName()).isEqualTo("UserInfoEntity");
    17. assertThat(UserInfoEntity.class.getName()).isEqualTo("cn.horse.reflect.entity.UserInfoEntity");
    18. assertThat(UserInfoEntity.class.getPackage().getName()).isEqualTo("cn.horse.reflect.entity");
    19. }
    20. @Test
    21. public void testPrimitive() {
    22. assertThat(byte.class.isPrimitive()).isTrue();
    23. assertThat(short.class.isPrimitive()).isTrue();
    24. assertThat(int.class.isPrimitive()).isTrue();
    25. assertThat(long.class.isPrimitive()).isTrue();
    26. assertThat(float.class.isPrimitive()).isTrue();
    27. assertThat(double.class.isPrimitive()).isTrue();
    28. assertThat(boolean.class.isPrimitive()).isTrue();
    29. assertThat(void.class.isPrimitive()).isTrue();
    30. assertThat(int[].class.isPrimitive()).isFalse();
    31. assertThat(String.class.isPrimitive()).isFalse();
    32. assertThat(UserInfoEntity.class.isPrimitive()).isFalse();
    33. }
    34. @Test
    35. public void testArray() {
    36. assertThat(String[].class.isArray()).isTrue();
    37. assertThat(String[].class.getComponentType()).isEqualTo(String.class);
    38. }
    39. @Test
    40. public void testEnum() {
    41. assertThat(Locale.Category.class.isEnum()).isTrue();
    42. Collection enumConstantList = Arrays.asList(Locale.Category.class.getEnumConstants());
    43. List expectedEnumConstantList = Arrays.asList(Locale.Category.values());
    44. assertThat(enumConstantList.size()).isEqualTo(expectedEnumConstantList.size());
    45. assertThat(enumConstantList).containsAll(expectedEnumConstantList);
    46. }
    47. @Test
    48. public void testAnnotation() {
    49. assertThat(SuppressWarnings.class.isAnnotation()).isTrue();
    50. }
    51. @Test
    52. public void testLocalClass() {
    53. // 定义局部类
    54. class LocalClass {
    55. }
    56. assertThat(LocalClass.class.isLocalClass()).isTrue();
    57. }
    58. @Test
    59. public void testAnonymousClass() {
    60. Runnable unknownClass = new Runnable() {
    61. @Override
    62. public void run() {
    63. }
    64. };
    65. assertThat(unknownClass.getClass().isAnonymousClass()).isTrue();
    66. }
    67. @Test
    68. public void testMemberClass() {
    69. assertThat(UserInfoEntity.class.isMemberClass()).isFalse();
    70. assertThat(InnerClass.class.isMemberClass()).isTrue();
    71. assertThat(StaticInnerClass.class.isMemberClass()).isTrue();
    72. // 定义局部类
    73. class LocalClass {
    74. }
    75. assertThat(LocalClass.class.isMemberClass()).isFalse();
    76. // 匿名类
    77. Runnable unknownClass = new Runnable() {
    78. @Override
    79. public void run() {
    80. }
    81. };
    82. assertThat(unknownClass.getClass().isMemberClass()).isFalse();
    83. }
    84. @Test
    85. public void testGetModifiers() {
    86. assertThat(Modifier.isPublic(UserInfoEntity.class.getModifiers())).isTrue();
    87. assertThat(Modifier.isProtected(UserInfoEntity.class.getModifiers())).isFalse();
    88. assertThat(Modifier.isPrivate(UserInfoEntity.class.getModifiers())).isFalse();
    89. assertThat(Modifier.isAbstract(UserInfoEntity.class.getModifiers())).isFalse();
    90. assertThat(Modifier.isInterface(UserInfoEntity.class.getModifiers())).isFalse();
    91. assertThat(Modifier.isStatic(UserInfoEntity.class.getModifiers())).isFalse();
    92. assertThat(Modifier.isFinal(UserInfoEntity.class.getModifiers())).isFalse();
    93. assertThat(Modifier.isNative(UserInfoEntity.class.getModifiers())).isFalse();
    94. }
    95. @Test
    96. public void testStaticInnerClass() {
    97. assertThat(Modifier.isStatic(StaticInnerClass.class.getModifiers())).isTrue();
    98. }
    99. @Test
    100. public void testInnerClass() {
    101. assertThat(InnerClass.class.isMemberClass() && !Modifier.isStatic(InnerClass.class.getModifiers())).isTrue();
    102. }
    103. private static class StaticInnerClass { }
    104. private class InnerClass { }
    105. @Test
    106. public void testTypeConvert() {
    107. assertThat(UserInfoEntity.class.isInstance(new UserInfoEntity(1L))).isTrue();
    108. assertThat(BaseEntity.class.isInstance(new UserInfoEntity(1L))).isTrue();
    109. assertThat(UserInfoEntity.class.isAssignableFrom(UserInfoEntity.class)).isTrue();
    110. assertThat(BaseEntity.class.isAssignableFrom(UserInfoEntity.class)).isTrue();
    111. assertThat(BaseEntity.class.cast(new UserInfoEntity(1L))).isNotNull();
    112. assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> BaseEntity.class.cast(1));
    113. }
    114. @Test
    115. public void testGetAnnotations() {
    116. Collectionextends Annotation>> annotationList = Arrays.stream(UserInfoEntity.class.getAnnotations()).map(Annotation::annotationType).collect(Collectors.toList());
    117. Listextends Annotation>> expectedAnnotationList = Arrays.asList(InheritedEntityAnnotation.class, UserInfoEntityAnnotation.class);
    118. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    119. assertThat(annotationList).containsAll(expectedAnnotationList);
    120. }
    121. @Test
    122. public void testGetAnnotationsByType() {
    123. Collectionextends Annotation>> annotationList = Arrays.stream(UserInfoEntity.class.getAnnotationsByType(InheritedEntityAnnotation.class)).map(Annotation::annotationType).collect(Collectors.toList());
    124. Listextends Annotation>> expectedAnnotationList = Arrays.asList(InheritedEntityAnnotation.class);
    125. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    126. assertThat(annotationList).containsAll(expectedAnnotationList);
    127. }
    128. @Test
    129. public void testGetAnnotation() {
    130. assertThat(UserInfoEntity.class.getAnnotation(EntityAnnotation.class)).isNull();
    131. assertThat(UserInfoEntity.class.getAnnotation(InheritedEntityAnnotation.class)).isNotNull();
    132. assertThat(UserInfoEntity.class.getAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
    133. }
    134. @Test
    135. public void testGetDeclaredAnnotations() {
    136. Collectionextends Annotation>> annotationList = Arrays.stream(UserInfoEntity.class.getDeclaredAnnotations()).map(Annotation::annotationType).collect(Collectors.toList());
    137. Listextends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class);
    138. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    139. assertThat(annotationList).containsAll(expectedAnnotationList);
    140. }
    141. @Test
    142. public void testGetDeclaredAnnotationsByType() {
    143. Collectionextends Annotation>> annotationList = Arrays.stream(UserInfoEntity.class.getDeclaredAnnotationsByType(UserInfoEntityAnnotation.class)).map(Annotation::annotationType).collect(Collectors.toList());
    144. Listextends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class);
    145. assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
    146. assertThat(annotationList).containsAll(expectedAnnotationList);
    147. }
    148. @Test
    149. public void testGetDeclaredAnnotation() {
    150. assertThat(UserInfoEntity.class.getDeclaredAnnotation(EntityAnnotation.class)).isNull();
    151. assertThat(UserInfoEntity.class.getDeclaredAnnotation(InheritedEntityAnnotation.class)).isNull();
    152. assertThat(UserInfoEntity.class.getDeclaredAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
    153. }
    154. }

    单元测试类中定义了两个内部类:静态内部类StaticInnerClass、内部类InnerClass;

    单元测试方法介绍:

    testGetName获取类名称,其中getSimpleName用于获取简略名称,getName用于获取全限类名,getPackage用于获取包对象

    testPrimitive判断是否是基本数据类型,使用isPrimitive方法判断是否是基本数据类型(byte,short,int,long,float,double,Boolean,void)

    testArray判断并获取数组元素类型,使用isArray判断是否是数组类型,使用getComponentType获取数组元素类型

    testEnum判断并获取枚举常量数组,使用isEnum判断是否是枚举类型,使用getEnumConstants获取枚举常量数组

    testAnnotation判断是否是注解类型,使用isAnnotation判断是否是注解类型

    testLocalClass判断是否是局部类,使用isLocalClass判断是否是局部类

    testAnonymousClass判断是否是匿名类,使用isAnonymousClass判断是否是匿名类

    testMemberClass判断是否是成员类,使用isMemberClass判断是否是成员类,内部类、静态内部类都属于成员类,局部类、匿名类都不属于成员类

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

    testStaticInnerClass判断是否是静态内部类,使用getModifiers获取修饰符,并使用Modifier类提供的静态方法判断是否使用了static修饰符

    testInnerClass判断是否是内部类,判断是否是成员类并且没有使用static修饰符

    testTypeConvert类型判断与转换,使用isInstance或isAssignableFrom可以判断类型是否可以转换,使用cast可以进行类型的转换。

    testGetAnnotations使用getAnnotations获取当前类及其父类可以被继承的注解

    testGetAnnotationsByType使用getAnnotationsByType从当前类及其父类可以被继承的注解中获取指定类型的注解

    testGetAnnotation使用getAnnotation从当前类及其父类可以被继承的注解中获取指定类型的注解

    testGetDeclaredAnnotations使用getDeclaredAnnotations获取当前类的注解

    testGetDeclaredAnnotationsByType使用getDeclaredAnnotationsByType从当前类的注解中获取指定类型的注解

    testGetDeclaredAnnotation使用getDeclaredAnnotation从当前类的注解中获取指定类型的注解

  • 相关阅读:
    修改ant-design-vue的switch样式,去除顿顿的样式
    高斯混合模型GMM及EM迭代求解算法(含代码实现)
    QODBC查询Oracle中文乱码问题
    Windows如何体验使用Linux
    家电生产线数控机床上下料长臂机器人组设计
    pytorch中nn.Parameter()使用方法
    【机器学习】有监督学习算法之:逻辑回归
    QFluentWidgets: 基于 C++ Qt 的 Fluent Design 组件库
    C++ | 大小端模式的概念、检测与影响
    腾讯测试大鸟分享4个关于 Python 函数(方法)的冷知识
  • 原文地址:https://blog.csdn.net/m1729339749/article/details/133911232