在上篇分析MetaObejct时候,MetaObejct的方法的实现是依赖ObjectWrapper,ObjectWrapper依赖于MetaClass,而MetaClass依赖于Reflector,这一节我们就来看看Reflector
//Reflector
public class Reflector { private static boolean classCacheEnabled = true; private static final String EMPTY_STRING_ARRAY[] = new String[0]; private static final Map REFLECTOR_MAP = new ConcurrentHashMap(); private Class type; private String readablePropertyNames[];//可读属性名 private String writeablePropertyNames[];//可写属性名 private Map setMethods;Map<String,MethodInvoker> private Map getMethods;Map<String,MethodInvoker> private Map setTypes;Map<String,Class> private Map getTypes;Map<String,Class> private Constructor defaultConstructor;//默认构造函数 private Map caseInsensitivePropertyMap;//大小写不敏感属性Map //构造Class对应的Reflector public static Reflector forClass(Class clazz) { if(classCacheEnabled) { //如果缓存状态开启,则从REFLECTOR_MAP获取对应的Reflector,没有则重新构建 Reflector cached = (Reflector)REFLECTOR_MAP.get(clazz); if(cached == null) { cached = new Reflector(clazz); REFLECTOR_MAP.put(clazz, cached); } return cached; } else { return new Reflector(clazz); } } private Reflector(Class clazz) { readablePropertyNames = EMPTY_STRING_ARRAY;//可读属性名 writeablePropertyNames = EMPTY_STRING_ARRAY;//可写属性名 setMethods = new HashMap();//Set方法Map getMethods = new HashMap();//Get方法Map setTypes = new HashMap(); getTypes = new HashMap(); caseInsensitivePropertyMap = new HashMap();//大小写不敏感属性Map type = clazz; addDefaultConstructor(clazz); addGetMethods(clazz); addSetMethods(clazz); addFields(clazz); readablePropertyNames = (String[])getMethods.keySet().toArray(new String[getMethods.keySet().size()]); writeablePropertyNames = (String[])setMethods.keySet().toArray(new String[setMethods.keySet().size()]); //将可读属性添加大小写不敏感属性Map String arr$[] = readablePropertyNames; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String propName = arr$[i$]; caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } //将可写属性添加大小写不敏感属性Map arr$ = writeablePropertyNames; len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String propName = arr$[i$]; caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } }
来看addDefaultConstructor
初始化默认构造函数为,无参构造函数
private void addDefaultConstructor(Class clazz) { Constructor consts[] = clazz.getDeclaredConstructors(); Constructor arr$[] = consts; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { Constructor constructor = arr$[i$]; if(constructor.getParameterTypes().length != 0) continue; if(canAccessPrivateMethods()) try { constructor.setAccessible(true); } catch(Exception e) { } if(constructor.isAccessible()) defaultConstructor = constructor; } }
来看addGetMethods
将Class的Get方法添加到
private void addGetMethods(Class cls) { Map conflictingGetters = new HashMap(); Method methods[] = getClassMethods(cls); Method arr$[] = methods; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { Method method = arr$[i$]; String name = method.getName(); if(name.startsWith("get") && name.length() > 3) { if(method.getParameterTypes().length == 0) { name = PropertyNamer.methodToProperty(name); //将name对应的get方法添加到conflictingGetters-Map中 addMethodConflict(conflictingGetters, name, method); } continue; } if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0) { name = PropertyNamer.methodToProperty(name); addMethodConflict(conflictingGetters, name, method); } } //解决方法冲突 resolveGetterConflicts(conflictingGetters); } private void addMethodConflict(Map conflictingMethods, String name, Method method) { List list = (List)conflictingMethods.get(name); if(list == null) { list = new ArrayList(); conflictingMethods.put(name, list); } list.add(method); } private void resolveGetterConflicts(Map conflictingGetters) { for(Iterator i$ = conflictingGetters.keySet().iterator(); i$.hasNext();) { String propName = (String)i$.next(); List getters = (List)conflictingGetters.get(propName); Iterator iterator = getters.iterator(); Method firstMethod = (Method)iterator.next(); if(getters.size() == 1) { addGetMethod(propName, firstMethod); } else { Method getter = firstMethod; Class getterType = firstMethod.getReturnType(); do { if(!iterator.hasNext()) break; Method method = (Method)iterator.next(); Class methodType = method.getReturnType(); if(methodType.equals(getterType)) throw new ReflectionException((new StringBuilder()).append("Illegal overloaded getter method with ambiguous type for property ").append(propName).append(" in class ").append(firstMethod.getDeclaringClass()).append(". This breaks the JavaBeans ").append("specification and can cause unpredicatble results.").toString()); if(!methodType.isAssignableFrom(getterType)) if(getterType.isAssignableFrom(methodType)) { getter = method; getterType = methodType; } else { throw new ReflectionException((new StringBuilder()).append("Illegal overloaded getter method with ambiguous type for property ").append(propName).append(" in class ").append(firstMethod.getDeclaringClass()).append(". This breaks the JavaBeans ").append("specification and can cause unpredicatble results.").toString()); } } while(true); //将name对应的get方法添加到getMethods集合中 addGetMethod(propName, getter); } } } //将name对应的get方法添加到getMethods集合中 private void addGetMethod(String name, Method method) { if(isValidPropertyName(name)) { getMethods.put(name, new MethodInvoker(method)); getTypes.put(name, method.getReturnType()); } }
来看addSetMethods
private void addSetMethods(Class cls) { Map conflictingSetters = new HashMap(); Method methods[] = getClassMethods(cls); Method arr$[] = methods; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { Method method = arr$[i$]; String name = method.getName(); if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) { name = PropertyNamer.methodToProperty(name); //将name对应的set方法添加到conflictingSetters-Map中 addMethodConflict(conflictingSetters, name, method); } } //解决方法冲突 resolveSetterConflicts(conflictingSetters); } private void addMethodConflict(Map conflictingMethods, String name, Method method) { List list = (List)conflictingMethods.get(name); if(list == null) { list = new ArrayList(); conflictingMethods.put(name, list); } list.add(method); } private void resolveSetterConflicts(Map conflictingSetters) { Iterator i$ = conflictingSetters.keySet().iterator(); do { if(!i$.hasNext()) break; String propName = (String)i$.next(); List setters = (List)conflictingSetters.get(propName); Method firstMethod = (Method)setters.get(0); if(setters.size() == 1) { addSetMethod(propName, firstMethod); continue; } Class expectedType = (Class)getTypes.get(propName); if(expectedType == null) throw new ReflectionException((new StringBuilder()).append("Illegal overloaded setter method with ambiguous type for property ").append(propName).append(" in class ").append(firstMethod.getDeclaringClass()).append(". This breaks the JavaBeans ").append("specification and can cause unpredicatble results.").toString()); Iterator methods = setters.iterator(); Method setter = null; do { if(!methods.hasNext()) break; Method method = (Method)methods.next(); if(method.getParameterTypes().length != 1 || !expectedType.equals(method.getParameterTypes()[0])) continue; setter = method; break; } while(true); if(setter == null) throw new ReflectionException((new StringBuilder()).append("Illegal overloaded setter method with ambiguous type for property ").append(propName).append(" in class ").append(firstMethod.getDeclaringClass()).append(". This breaks the JavaBeans ").append("specification and can cause unpredicatble results.").toString()); //将对应的set方法添加到setMethods-map中 addSetMethod(propName, setter); } while(true); } private void addSetMethod(String name, Method method) { if(isValidPropertyName(name)) { setMethods.put(name, new MethodInvoker(method)); setTypes.put(name, method.getParameterTypes()[0]); } }
来看addFields
private void addFields(Class clazz) { Field fields[] = clazz.getDeclaredFields(); Field arr$[] = fields; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { Field field = arr$[i$]; if(canAccessPrivateMethods()) try { field.setAccessible(true); } catch(Exception e) { } if(!field.isAccessible()) continue; if(!setMethods.containsKey(field.getName())) addSetField(field); if(!getMethods.containsKey(field.getName())) addGetField(field); } if(clazz.getSuperclass() != null) addFields(clazz.getSuperclass()); } //将Field的对应set方法,及参数类型添加到setMethods,setTypes-Map中 private void addSetField(Field field) { if(isValidPropertyName(field.getName())) { setMethods.put(field.getName(), new SetFieldInvoker(field)); setTypes.put(field.getName(), field.getType()); } } //将Field的对应get方法,及参数类型添加到setMethods,setTypes-Map中 private void addGetField(Field field) { if(isValidPropertyName(field.getName())) { getMethods.put(field.getName(), new GetFieldInvoker(field)); getTypes.put(field.getName(), field.getType()); } }
总结:
从以上分析,Reflector构造函数,所做的工作为,初始构造函数,将Class的set与get方法及参数添加到setMethods,getMethods,setTypes,getTypes对应的Map中,setMethods,getMethods Map的key属性名,value为对应的方法,然后初始化可读,可写,及大小写不明感属性集合。