Reflector类负责对一个类进行反射解析,并将解析后的结果在属性中存储起来。
一个类反射解析后都有哪些属性呢?我们可以通过Reflector类定义的属性来查看
public class Reflector {
// 要被反射解析的类
private final Class<?> type;
// 可读属性列表即有get方法的属性列表
private final String[] readablePropertyNames;
// 可写属性列表即有set方法的属性列表
private final String[] writeablePropertyNames;
// set方法映射表。键为属性名,值为对应的set方法
private final Map<String, Invoker> setMethods = new HashMap<String, Invoker>();
// get方法映射表。键为属性名,值为对应的get方法
private final Map<String, Invoker> getMethods = new HashMap<String, Invoker>();
// set方法输入参数类型映射表。键为属性名,值为对应set方法输入参数类型的Class
private final Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>();
// get方法返回值类型映射表。键为属性名,值为对应get方法返回值类型的Class
private final Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>();
// 默认构造器
private Constructor<?> defaultConstructor;
// 忽略大小写的属性映射表。键为属性名全大写值,值为属性名
private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();
// Reflector类反射解析一个类的过程是由构造函数触发的
public Reflector(Class<?> clazz) {
// 记录被反射解析的类
type = clazz;
// 解析默认造方法
addDefaultConstructor(clazz);
// 解析所有的getter
addGetMethods(clazz);
// 解析所有的setter
addSetMethods(clazz);
// 解析所有属性
addFields(clazz);
// 获取可读属性列表
readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
// 获取可写属性列表
writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
// 获取忽略大小写的属性列表
for (String propName : readablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
for (String propName : writeablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
}
.....
}
测试案例:
@Test
public void test1()throws Exception{
Reflector reflector = new Reflector(User.class);
Class<?> type = reflector.getType();
System.out.println("要被反射解析的类:"+type);
Constructor<?> defaultConstructor = reflector.getDefaultConstructor();
System.out.println(defaultConstructor);
String[] getablePropertyNames = reflector.getGetablePropertyNames();
for (String propertyName : getablePropertyNames) {
System.out.println("可读属性:"+propertyName);
}
System.out.println("----------------------------------------------------------");
String[] setablePropertyNames = reflector.getSetablePropertyNames();
for (String propertyName : setablePropertyNames) {
System.out.println("可写属性:"+propertyName);
}
System.out.println("--------------------------------------------------");
for (String propertyName : reflector.getGetablePropertyNames()) {
Invoker name = reflector.getGetInvoker(propertyName);
Object invoke = name.invoke(new User(), null);
System.out.println("执行属性"+propertyName+"的get方法:"+invoke);
}
}
测试结果:
该类里面还有一个值的注意的小工具类可以直接拿来使用,生成方法签名
private String getSignature(Method method) {
StringBuilder sb = new StringBuilder();
Class<?> returnType = method.getReturnType();
if (returnType != null) {
sb.append(returnType.getName()).append('#');
}
sb.append(method.getName());
Class<?>[] parameters = method.getParameterTypes();
for (int i = 0; i < parameters.length; i++) {
if (i == 0) {
sb.append(':');
} else {
sb.append(',');
}
sb.append(parameters[i].getName());
}
return sb.toString();
}