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