package application.util; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; public class Reflections { private Class<?> clazz; private Object object; public Reflections(Object object) { if (object == null) return; this.object = object; this.clazz = object.getClass(); } private static class NULL {} public interface MethodCallback{ void done(Object returnValue); } public static Reflections newInstance(){ return new Reflections(null); } public static Reflections on(Object object){ return new Reflections(object); } private Map<String, Field> fields() { Map<String, Field> fieldsMap = new LinkedHashMap<String, Field>(); Class tempClazz = clazz; while(tempClazz != null){ for(Field field : tempClazz.getDeclaredFields()){ if(!fieldsMap.containsKey(field.getName())){ fieldsMap.put(field.getName(), field); } } tempClazz = tempClazz.getSuperclass(); } return fieldsMap; } private static Class<?>[] types(Object... values) { if (values == null) { // �� return new Class[0]; } Class<?>[] results = new Class[values.length]; for (int i = 0; i < values.length; i++) { Object value = values[i]; results[i] = value == null ? NULL.class : value.getClass(); } return results; } public Reflections set(String key, Object value) { try { Field field = getField(key); field.set(object, value); } catch (Exception e) { e.printStackTrace(); } return this; } @SuppressWarnings("unchecked") public <T> T create(Class<T> clazz, Object... args){ try { Class[] parameterTypes = types(args); for (Constructor<?> constructor : clazz.getDeclaredConstructors()) { if(matchMethod(constructor.getParameterTypes(), parameterTypes)){ constructor.setAccessible(true); return (T) constructor.newInstance(args); } } } catch (Exception e) { e.printStackTrace(); } return null; } public Reflections callMethod(String methodName, MethodCallback callback, Object ... params) { try { Class[] parameterTypes = types(params); Method method = getMethod(methodName,parameterTypes); method.setAccessible(true); if(method.getReturnType() == void.class){ method.invoke(object, params); }else{ Object returnValue = method.invoke(object, params); if(callback != null) callback.done(returnValue); } } catch (Exception e) { e.printStackTrace(); } return this; } private Field getField(String key) { try { // �ȳ��Թ��з����Ļ�ȡ(��Ϊ���Ի�ȡ���̳е�,��Χ����) return this.clazz.getField(key); } catch (NoSuchFieldException e) { // �ٳ���˽�з����Ļ�ȡ(��֧�ֱ����еķ���) try { Field field = this.clazz.getDeclaredField(key); field.setAccessible(true); return field; } catch (NoSuchFieldException ee) { throw new RuntimeException("No Such Field: " + key); } } } private Method getMethod(String methodName, Class[] parameterTypes) { // ƥ�乫�з���: for (Method method : this.clazz.getMethods()) { if (method.getName().equals(methodName) && matchMethod(method.getParameterTypes(), parameterTypes)) { return method; } } // ƥ��˽�з��� for (Method method : this.clazz.getDeclaredMethods()) { if (method.getName().equals(methodName) && matchMethod(method.getParameterTypes(), parameterTypes)) { return method; } } throw new RuntimeException("No Such Method: " + methodName); } private boolean matchMethod(Class[] currentParamsTypes, Class[] parameterTypes) { if(currentParamsTypes.length == parameterTypes.length){ for(int i = 0;i < parameterTypes.length;i++){ if(parameterTypes[i] == NULL.class){ continue; } if(wrapper(currentParamsTypes[i]).isAssignableFrom(wrapper(parameterTypes[i]))){ continue; } return false; } return true; } return false; } public Object get(String key) { try { Field field = getField(key); return field.get(object); } catch (Exception e) { e.printStackTrace(); } return null; } public static Class<?> wrapper(Class<?> type) { if (type == null) { return null; } else if (type.isPrimitive()) { // isPrimitive �Ƿ��ǻ������� if (boolean.class == type) { return Boolean.class; } else if (int.class == type) { return Integer.class; } else if (long.class == type) { return Long.class; } else if (short.class == type) { return Short.class; } else if (byte.class == type) { return Byte.class; } else if (double.class == type) { return Double.class; } else if (float.class == type) { return Float.class; } else if (char.class == type) { return Character.class; } else if (void.class == type) { return Void.class; } } return type; } }