package li.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import li.datasource.SimpleDataSource; import li.util.test.DestModel; import li.util.test.SrcModel; import org.junit.Before; import org.junit.Test; public class ReflectTest { private static final Log log = Log.init(); DestModel attr = new DestModel(); SrcModel srcModel = new SrcModel(); DestModel destModel = new DestModel(); @Before public void before() { attr.attr1 = "Model2.attr.attr1"; srcModel.attr1 = "123123"; srcModel.attr2 = false; srcModel.destModel = attr; } @Test public void fieldType() { System.out.println(Reflect.fieldType(SimpleDataSource.class, "loginTimeout")); Integer loginTimeout = 1; Reflect.set(new SimpleDataSource(), "loginTimeout", loginTimeout); } @Test public void argNames() { Method method = Reflect.getMethod(Reflect.class, "argNames", Method.class); String[] argNames = Reflect.argNames(method); for (String argName : argNames) { log.debug(argName); } } @Test public void copy() { Reflect.copy(srcModel, destModel); assertEquals("123123", destModel.attr1); assertEquals(false, destModel.attr2); assertEquals(attr, destModel.destModel); } @Test public void getTest1() { int num = 100; long start = System.currentTimeMillis(); Map<String, String> map = new HashMap<String, String>(); for (int i = 0; i < num; i++) { Object result = Reflect.get(map, "none"); } log.debug("新版本的 get 执行 " + num + " 次 耗时 " + (System.currentTimeMillis() - start)); } @Test public void getTest2() { int num = 100; long start = System.currentTimeMillis(); Map<String, String> map = new HashMap<String, String>(); for (int i = 0; i < num; i++) { Object result = get2(map, "none"); } log.debug("老版本的 get 执行 " + num + " 次 耗时 " + (System.currentTimeMillis() - start)); } /** * 老版本的方法,做对比 */ public static Object get2(Object target, String fieldName) { try { String method = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method getter = Reflect.getMethod(target.getClass(), method); return getter.invoke(target);// 使用Getter方法 } catch (Exception e) {// 没有匹配的Getter方法 try { return Reflect.getField(target.getClass(), fieldName).get(target);// 通过属性访问 } catch (Exception ex) { if (target instanceof Map) { return ((Map) target).get(fieldName);// 通过Record.get()方法 } else { throw new RuntimeException("Reflect.get() target=" + target + ",fieldName=" + fieldName); } } } } @Test public void setTest1() { int num = 100; long start = System.currentTimeMillis(); Map<String, String> map = new HashMap<String, String>(); for (int i = 0; i < num; i++) { Reflect.set(map, "f", "v"); } log.debug("新版本的 set 执行 " + num + " 次 耗时 " + (System.currentTimeMillis() - start)); } @Test public void setTest2() { int num = 100; long start = System.currentTimeMillis(); Map<String, String> map = new HashMap<String, String>(); for (int i = 0; i < num; i++) { set2(map, "f", "v"); } log.debug("老版本的 set 执行 " + num + " 次 耗时 " + (System.currentTimeMillis() - start)); } /** * 老版本方法,供对比 */ public static void set2(Object target, String fieldName, Object value) { try { String method = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method setter = Reflect.getMethod(target.getClass(), method, Reflect.fieldType(target.getClass(), fieldName)); setter.invoke(target, value);// 使用Setter方法,这里没做类型转换 } catch (Exception e) {// 没有匹配的Setter方法 try { Field field = Reflect.getField(target.getClass(), fieldName); field.set(target, Convert.toType(field.getType(), value));// 通过属性访问,这里有做类型转换 } catch (Exception ex) { if (target instanceof Map) { ((Map) target).put(fieldName, value);// 通过Record.set()方法,这里也没做类型转换 } else { throw new RuntimeException("Reflect.set() target=" + target + ",fieldName=" + fieldName + ",value=" + value); } } } } @Test public void fieldType1() { int num = 100; long start = System.currentTimeMillis(); for (int i = 0; i < num; i++) { Class<?> type = Reflect.fieldType(li.dao.AbstractDao.class, "beanMeta"); } log.debug("新版本的 fieldType 执行 " + num + " 次 耗时 " + (System.currentTimeMillis() - start)); } @Test public void fieldType2() { int num = 100; long start = System.currentTimeMillis(); for (int i = 0; i < num; i++) { Class<?> type = fieldType2(li.dao.AbstractDao.class, "beanMeta"); } log.debug("老版本的 fieldType 执行 " + num + " 次 耗时 " + (System.currentTimeMillis() - start)); } /** * 老版本,供性能对比 */ public static Class<?> fieldType2(Class<?> targetType, String fieldName) { String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method[] methods = targetType.getMethods(); for (Method method : methods) { if (1 == method.getParameterTypes().length && method.getName().equals(setterName)) { return method.getParameterTypes()[0];// 从setter探测 } } Field field = Reflect.getField(targetType, fieldName); if (null != field) { // 从field探测 return field.getType(); } String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method getter = Reflect.getMethod(targetType, getterName); if (null != getter) {// 从getter探测 return getter.getReturnType(); } return null; } @Test public void testActualType() { assertNull(Reflect.actualTypes(ReflectTest.class)); } }