回顾反射机制、注解
大约 2 分钟
反射机制实现方法调用
调⽤⼀个⽅法,⼀般涉及到4个要素:
- 调⽤哪个对象的(调用对象)
- 哪个⽅法(方法名)
- 传什么参数(实际参数列表)
- 返回什么值(返回值)
获取 Method
Class clazz = Class.forName("com.powernode.reflect.SystemService");
// 通过 Class 获取类中的方法
// 参数(可变长):方法名,参数类型(构成形式参数列表)
Method loginMethod = clazz.getDeclaredMethod("login", String.class, String.class);获取的 Method对象包含了:
- 方法名
- 形式参数列表
- 返回值类型(根据方法签名解析)
调用 Method
通过 Method 对象调用对象的这个方法,仍需要提供:
- 调用对象
- 实际参数
// 调用对象 obj
// 可变长参数囊括所有的实际参数
// retValue方法返回值,void时为 null
Object retValue = loginMethod.invoke(obj, "admin", "admin123");反射机制允许接收外部参数来动态实现对方法的调用,依据java规范(如bean规范)可以进一步简化需要的外部参数,达到动态地操作对象。
注解
注解的存在用于对对类、方法等进行标记,从而向编译器或框架传达信息,对于框架而言,可以简化配置,方便开发。
注解的定义
// 用在注解上的注解——元注解
// 指定这个注解可以出现的位置,ElementType.TYPE表示可以出现在类(接口)的定义上
@Target(value = {ElementType.TYPE})
// 注解的保持性策略:RUNTIME 表示运行时也存在,即可以使用反射机制可以读取到这个注解
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Component {
String value(); // 注解的属性,属性名为 value
}注解的使用
// 在需要的地方使用 @注解类型名(属性名=属性值, ...) 即可
@Component(value = "userBean")
public class User {
}- 使用时,当注解属性名只有1个且为 value时,
value=可以不写。 - 使用时,若属性值为数组且只有1个元素,则
{}可以不写。
反射机制读取注解
Class<?> clazz = Class.forName(className);
// clazz.isAnnotationPresent 方法用于读取类上的注解(保持性策略为 RUNTIME才可读取到)
if (clazz.isAnnotationPresent(Component.class)) {
// 存在,则获取这个注解对象
Component component = clazz.getAnnotation(Component.class);
// 获取注解的属性值
String beanId = component.value();
// ...
}