反射

  1. 反射调用方法并不是通过调用时的传参确定方法重载,而是在获取方法的时候通过方法名和参数类型来确定的。遇到方法有包装类型和基本类型重载的时候,需要特别注意。 ```java // 调用 get(int age) getClass().getDeclaredMethod(“age”, Integer.TYPE).invoke(this, Integer.valueOf(“36”));

// 调用 get(Integer age) getClass().getDeclaredMethod(“age”, Integer.class).invoke(this, Integer.valueOf(“36”))

  1. 2. 反射获取类成员,需要注意 getXXX getDeclaredXXX 方法的区别,其中 XXX 包括 MethodsFieldsConstructorsAnnotations。这两类方法,针对不同的成员类型XXX 和对象,在实现上都有一些细节差异。比如 getDeclaredMethods 方法无法获得父类定义的方法,而 getMethods 方法可以,只是差异之一,不能适用于所有的 XXX
  2. <a name="ud4XJ"></a>
  3. ## 泛型
  4. - 泛型因为类型擦除会导致泛型方法 T 占位符被替换为 Object,子类如果使用具体类型覆盖父类实现,实际上编译器会生成桥接方法。这样既满足子类方法重写父类方法的定义,又满足子类实现的方法有具体的类型。使用反射来获取方法清单时,需要特别注意这一点。
  5. - 反射进行方法调用要注意过滤桥接方法。使用 `getClass().getDeclaredMethod().isBridge()` 进行判断
  6. - 通过 getDeclaredMethods 方法获取到所有方法后,必须同时根据方法名 setValue 和非 isBridge 两个条件过滤,才能实现唯一过滤;
  7. - 使用 Stream 时,如果希望只匹配 0 1 项的话,可以考虑配合 ifPresent 来使用findFirst 方法。
  8. <a name="CsuPq"></a>
  9. ## 注解
  10. - 自定义注解可以通过标记元注解 @Inherited 实现注解的继承,不过这**只适用于类**。如果要继承定义在接口或方法上的注解,可以使用 Spring 的工具类 AnnotatedElementUtils,并注意各种 getXXX 方法和 findXXX 方法的区别。
  11. ---
  12. <a name="K2CDK"></a>
  13. ## 使用
  14. <a name="gYgrV"></a>
  15. ### 泛型类
  16. - 可以用 extends 修饰类型
  17. ```java
  18. public class Person<E extends xxx> implements Comparator<E> {
  19. //
  20. }

泛型方法

  • 第一个修饰符可以用来限定返回值(通过 extends
    1. public <E extends XXX> doSomething<E>() {
    2. //
    3. }