当前位置: 首页 > news >正文

怎样做企业的网站首页/郑州seo优化外包

怎样做企业的网站首页,郑州seo优化外包,一个专门做预告片的网站,临沂网站建设哪家好2019独角兽企业重金招聘Python工程师标准>>> 属性存取,方法调用是最Java反射最常用也是最基本的功能。虽然已经有commons-beanutils实现在前,但出于种种考虑,还是自己实现了一遍。经过一段时间的思考重构,终于将原来一…

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

属性存取,方法调用是最Java反射最常用也是最基本的功能。虽然已经有commons-beanutils实现在前,但出于种种考虑,还是自己实现了一遍。经过一段时间的思考重构,终于将原来一些简单的想法渐渐实现并完善。

属性存取实现了根据getter/setter方法和直接访问Field两种方式。

方法调用主要实现了根据方法参数自动决定调用最特定的重载方法。

主要支持接口及类:

通用查找接口

public interface Lookup<K, V> {V find(K key);
}

类及名称

public class ClassNamePair {private final Class<?> clazz;private final String name;
...

方法名及参数

public class MethodIdentifier {private final Class<?> clazz;private final String name;private final Class<?>[] argumentTypes;
...

根据属性名查找Field

public class FieldLookup implements Lookup<ClassNamePair, Field> {
...

根据方法名、参数查找最特定Method

public class MethodLookup implements Lookup<MethodIdentifier, Method> {
...


实现:

1.根据属性名查找Field(public, protected, private, package)

按当前类->接口->超类的顺序搜索声明的Field即可。

public Field find(ClassNamePair key) {Field field = getDeclaredField(key.getClazz(), key.getName());if (field == null) {field = getInheritedFromInterfaces(key.getClazz(), key.getName());if (field == null) {field = getInheritedFromSuperclass(key.getClazz(), key.getName());}}return field;
}

在给定类/接口查找Field

private static Field getDeclaredField(Class<?> cls, String name) {for (Field field : cls.getDeclaredFields()) {if (field.getName().equals(name)) {return field;}}return null;
}

在此基础上,在接口及超类中查找也相当容易实现

private static Field getInheritedFromInterfaces(Class<?> cls, String name) {for (Class<?> i : cls.getInterfaces()) {Field field = getDeclaredField(i, name);if (field != null) {return field;}}return null;
}private static Field getInheritedFromSuperclass(Class<?> cls, String name) {for (Class<?> s = cls.getSuperclass(); s != null; s = s.getSuperclass()) {Field field = getDeclaredField(s, name);if (field != null) {return field;}}return null;
}

 

 2.根据方法名、参数查找合适Method(public)

 由于涉及方法重载(Overloading),所以根据方法名、参数查找合适的Method比较复杂。将之分解为多个步骤来实现。

2.1 根据方法名过滤并排序所有可能的方法

对Method进行一些简单的包装:方便后续查找

public class MethodSignature {private final Method method;private final Class<?>[] parameterTypes;private final Class<?> varArgType;public MethodSignature(Method method) {this.method = method;parameterTypes = method.getParameterTypes();varArgType = method.isVarArgs() ?parameterTypes[parameterTypes.length - 1].getComponentType() : null;}
...

重载方法查找:过滤->排序

public class OverloadingLookup implements Lookup<ClassNamePair, MethodSignature[]> {public MethodSignature[] find(ClassNamePair key) {return sort(filter(key.getClazz(), key.getName()));}
...

按方法名过滤,获取所有重载方法

private static MethodSignature[] filter(Class<?> cls, String name) {List<MethodSignature> overloadingMethods = new LinkedList<>();for (Method method : cls.getMethods()) {if (method.getName().equals(name)) {overloadingMethods.add(new MethodSignature(method));}}return overloadingMethods.toArray(new MethodSignature[overloadingMethods.size()]);
}

按参数长度由小到大排序,相同参数长度的方法,变元方法在前,定元方法在后,方便后续查找

public static final Comparator<MethodSignature> PARAM_LENGTH_COMPARATOR =new Comparator<MethodSignature>() {@Overridepublic int compare(MethodSignature o1, MethodSignature o2) {int c1 = Integer.compare(o1.getParameterTypes().length,o2.getParameterTypes().length);if (c1 == 0) {if (o1.isVarArgs()) {return o2.isVarArgs() ? 0 : -1;} else {return o2.isVarArgs() ? 1 : 0;}} else {return c1;}}};private static MethodSignature[] sort(MethodSignature[] overloadingMethods) {Arrays.sort(overloadingMethods, PARAM_LENGTH_COMPARATOR);return overloadingMethods;
}

 2.2 在重载方法中根据参数选择最特定的方法

这部分的思路参照了Java语言规范(JLS)15.12节 方法调用表达式。

JLS 15.12.2节编译期确定方法签名分为以下几个步骤:

1)不允许拆装箱及使用可变元数方法进行重载解析,即可由类型宽化(扩展基本转换、扩展引用转换)确定的匹配元数方法。(确保较老语言版本中任何有效的方法调用不会因为引入隐式拆装箱、可变元数方法而被当成不明确的)

2)允许拆装箱但不允许使用可变元数方法进行重载解析,即可由方法调用转换确定的匹配元数方法。(确保如果存在一个可用固定元数方法,可变元数方法就不会被调用)

3)允许拆装箱及使用可变元数方法进行重载解析。

以上每个步骤中,如果存在多个符合的方法,则需在它们中选择最特定的方法。

JLS 5.3节方法调用转换规定可包括以下转换:

  • 同一性转换:如int->int, Object->Object
  • 扩展基本转换:如short->int
  • 扩展引用转换:如String->Object
  • 装箱转换,可后接扩展引用转换:如int->Integer->Number
  • 拆箱转换,可后接扩展基本转换:如Short->short->int

public class MethodInvocationConversion {public static boolean isWideningPrimitiveConversion(Class<?> from, Class<?> to) {if (to == int.class) {return from == char.class ||from == short.class ||from == byte.class;}if (to == double.class) {return from == float.class ||from == long.class ||from == int.class ||from == char.class ||from == short.class ||from == byte.class;}if (to == short.class) {return from == byte.class;}if (to == long.class) {return from == int.class ||from == char.class ||from == short.class ||from == byte.class;}if (to == float.class) {return from == long.class ||from == int.class ||from == char.class ||from == short.class ||from == byte.class;}return false;}public static boolean isWideningReferenceConversion(Class<?> from, Class<?> to) {return to.isAssignableFrom(from);}public static Class<?> boxing(Class<?> cls) {if (cls == int.class) {return Integer.class;}if (cls == double.class) {return Double.class;}if (cls == boolean.class) {return Boolean.class;}if (cls == byte.class) {return Byte.class;}if (cls == char.class) {return Character.class;}if (cls == short.class) {return Short.class;}if (cls == long.class) {return Long.class;}if (cls == float.class) {return Float.class;}return null;}public static Class<?> unboxing(Class<?> cls) {if (cls == Integer.class) {return int.class;}if (cls == Double.class) {return double.class;}if (cls == Boolean.class) {return boolean.class;}if (cls == Byte.class) {return byte.class;}if (cls == Character.class) {return char.class;}if (cls == Short.class) {return short.class;}if (cls == Long.class) {return long.class;}if (cls == Float.class) {return float.class;}return null;}
}

确定方法签名时执行的转换可以分为类型宽化,方法调用转换两种,出于性能考虑,还可以加上完全匹配(全是同一性转换)。

public class MethodSignatureDeterminer {
...private static ApplicableKind checkApplicable(Class<?> from, Class<?> to) {if (to == from) {return ApplicableKind.MATCHING;}if (to.isPrimitive()) {if (from == null) {return null;}if (from.isPrimitive()) {return isWideningPrimitiveConversion(from, to) ?ApplicableKind.SUBTYPING : null;} else {Class<?> unboxingClass = unboxing(from);return (to == unboxingClass || isWideningPrimitiveConversion(unboxingClass, to)) ?ApplicableKind.METHOD_INVOCATION_CONVERSION : null;}} else {if (from == null) {return ApplicableKind.SUBTYPING;}if (from.isPrimitive()) {Class<?> boxingClass = boxing(from);return (to == boxingClass || isWideningReferenceConversion(boxingClass, to)) ?ApplicableKind.METHOD_INVOCATION_CONVERSION : null;} else {return isWideningReferenceConversion(from, to) ?ApplicableKind.SUBTYPING : null;}}}static enum ApplicableKind {MATCHING,SUBTYPING,METHOD_INVOCATION_CONVERSION;ApplicableKind combine(ApplicableKind that) {return this.compareTo(that) > 0 ? this : that;}}
...
}

固定元数方法、可变元数方法的判定

public class MethodSignatureDeterminer {
...private static boolean isMatchingArity(MethodSignature signature, MethodIdentifier id) {return !signature.isVarArgs() &&signature.getParameterTypes().length == id.getArgumentTypes().length;}private static boolean isVariableArity(MethodSignature signature, MethodIdentifier id) {return signature.isVarArgs() &&signature.getParameterTypes().length <= id.getArgumentTypes().length;}
...
}

在上述准备工作做好后,可通过JLS 15.12.2节中给出的算法实现各步骤。

步骤1、步骤2:固定元数方法的转换

public class MethodSignatureDeterminer {
...private static ApplicableKind checkApplicableMatchingArity(MethodSignature method,MethodIdentifier id) {if (method.getParameterTypes().length == 0) {return ApplicableKind.MATCHING;} else {ApplicableKind kind = null;final Class<?>[] paramTypes = method.getParameterTypes();final Class<?>[] argTypes = id.getArgumentTypes();for (int i = 0; i < paramTypes.length; ++i) {ApplicableKind paramKind = checkApplicable(argTypes[i], paramTypes[i]);if (paramKind == null) {return null;}kind = kind == null ? paramKind : kind.combine(paramKind);}return kind;}}
...
}

步骤3:可变元数方法的转换

public class MethodSignatureDeterminer {
...private static ApplicableKind checkApplicableVariableArity(MethodSignature method,MethodIdentifier id) {ApplicableKind kind = null;final Class<?>[] paramTypes = method.getParameterTypes();final int paramsLength = paramTypes.length;final Class<?>[] argTypes = id.getArgumentTypes();final int argsLength = argTypes.length;for (int i = 0; i < paramsLength - 1; ++i) {ApplicableKind paramKind = checkApplicable(argTypes[i], paramTypes[i]);if (paramKind == null) {return null;}kind = kind == null ? paramKind : kind.combine(paramKind);}Class<?> varArgType = method.getVarArgType();for (int i = paramsLength - 1; i < argsLength; ++i) {ApplicableKind paramKind = checkApplicable(argTypes[i], varArgType);if (paramKind == null) {return null;}kind = kind == null ? paramKind : kind.combine(paramKind);}return kind;}
...
}

选择最特定的方法

public class MethodSignatureDeterminer {
...private static boolean isMoreSpecificFixArity(MethodSignature m1, MethodSignature m2) {final Class<?>[] paramTypes1 = m1.getParameterTypes();final Class<?>[] paramTypes2 = m2.getParameterTypes();for (int i = 0; i < paramTypes1.length; ++i) {if (checkApplicable(paramTypes1[i], paramTypes2[i]) == null) {return false;}}return true;}private static boolean isMoreSpecificVariableArity(MethodSignature m1, MethodSignature m2) {final Class<?>[] paramTypes1 = m1.getParameterTypes();final int paramsLength1 = paramTypes1.length;final Class<?>[] paramTypes2 = m2.getParameterTypes();final int paramsLength2 = paramTypes2.length;if (paramsLength1 >= paramsLength2) {for (int i = 0; i < paramsLength2 - 1; ++i) {if (checkApplicable(paramTypes1[i], paramTypes2[i]) == null) {return false;}}Class<?> varArgType = m2.getVarArgType();for (int i = paramsLength2 - 1; i < paramsLength1; ++i) {if (checkApplicable(paramTypes1[i], varArgType) == null) {return false;}}return true;} else {for (int i = 0; i < paramsLength1 - 1; ++i) {if (checkApplicable(paramTypes1[i], paramTypes2[i]) == null) {return false;}}Class<?> varArgType = m1.getVarArgType();for (int i = paramsLength1 - 1; i < paramsLength2; ++i) {if (checkApplicable(varArgType, paramTypes2[i]) == null) {return false;}}return true;}}
...
}

确定方法签名的过程实质是一个有限状态转换机。

状态:开始(S), 类型宽化固定元数(P1),方法调用转换固定元数(P2),可变元数(P3),完成(F)

事件:不可转换(EN),匹配固定元数方法(EM),类型宽化固定元数方法(ES),方法调用转换固定元数方法(EC),可变元方法(EV)

S P1 P2 P3  FS EN ES EC EV EM
P1  X ES  X  X EM
P2  X ES EC  X EM
P3  X ES EC EV EMF  X  X  X  X  X

定义状态机:

public class MethodSignatureDeterminer {private Phase currentPhase;private MethodSignature mostSpecific;public MethodSignatureDeterminer() {this.currentPhase = Phase.START;}
...public void accept(MethodSignature signature, MethodIdentifier id) {currentPhase.accept(this, signature, id);}
...public static enum Phase {...abstract void accept(MethodSignatureDeterminer determiner,MethodSignature signature, MethodIdentifier id);}
...
}

开始:

START {@Overridefinal void accept(MethodSignatureDeterminer determiner,MethodSignature signature, MethodIdentifier id) {if (isMatchingArity(signature, id)) {ApplicableKind kind = checkApplicableMatchingArity(signature, id);if (kind != null) {determiner.mostSpecific = signature;switch (kind) {case MATCHING: {determiner.currentPhase = FINISH;break;}case SUBTYPING: {determiner.currentPhase = MATCHING_ARITY_BY_SUBTYPING;break;}case METHOD_INVOCATION_CONVERSION: {determiner.currentPhase = MATCHING_ARITY_BY_CONVERSION;break;}}}} else if (isVariableArity(signature, id)) {if (checkApplicableVariableArity(signature, id) != null) {determiner.mostSpecific = signature;determiner.currentPhase = VARIABLE_ARITY;}}}
}

 类型宽化固定元数:(由于是已排序的,所以固定元数方法搜索结束后可认为整个搜索过程结束)

MATCHING_ARITY_BY_SUBTYPING {@Overridefinal void accept(MethodSignatureDeterminer determiner,MethodSignature signature, MethodIdentifier id) {if (isMatchingArity(signature, id)) {ApplicableKind kind = checkApplicableMatchingArity(signature, id);if (kind != null) {switch (kind) {case MATCHING: {determiner.mostSpecific = signature;determiner.currentPhase = FINISH;break;}case SUBTYPING: {if (isMoreSpecificFixArity(signature, determiner.mostSpecific)) {determiner.mostSpecific = signature;}break;}}}} else {if (signature.getParameterTypes().length != id.getArgumentTypes().length) {determiner.currentPhase = FINISH;}}}
}

方法调用转换固定元数:(由于是已排序的,所以固定元数方法搜索结束后可认为整个搜索过程结束)

MATCHING_ARITY_BY_CONVERSION {@Overridefinal void accept(MethodSignatureDeterminer determiner,MethodSignature signature, MethodIdentifier id) {if (isMatchingArity(signature, id)) {ApplicableKind kind = checkApplicableMatchingArity(signature, id);if (kind != null) {switch (kind) {case MATCHING: {determiner.mostSpecific = signature;determiner.currentPhase = FINISH;break;}case SUBTYPING: {determiner.mostSpecific = signature;determiner.currentPhase = MATCHING_ARITY_BY_SUBTYPING;break;}case METHOD_INVOCATION_CONVERSION: {if (isMoreSpecificFixArity(signature, determiner.mostSpecific)) {determiner.mostSpecific = signature;}break;}}}} else {if (signature.getParameterTypes().length != id.getArgumentTypes().length) {determiner.currentPhase = FINISH;}}}
}

可变元数:

VARIABLE_ARITY {@Overridefinal void accept(MethodSignatureDeterminer determiner,MethodSignature signature, MethodIdentifier id) {if (isVariableArity(signature, id)) {if (checkApplicableVariableArity(signature, id) != null) {if (isMoreSpecificVariableArity(signature, determiner.mostSpecific)) {determiner.mostSpecific = signature;}}}}
}

完成:

FINISH {@Overridefinal void accept(MethodSignatureDeterminer determiner,MethodSignature signature, MethodIdentifier id) {//do nothing}
}

2.3 集成

将2.1,2.2的功能组合。

public class MethodLookup implements Lookup<MethodIdentifier, Method> {private final Lookup<ClassNamePair, MethodSignature[]> overloadingLookup;
...public Method find(MethodIdentifier key) {MethodSignature signature = determine(findOverloading(key), key);return signature == null ? null : signature.getMethod();}
...
}

获取所有重载方法

private MethodSignature[] findOverloading(MethodIdentifier id) {return overloadingLookup.find(new ClassNamePair(id.getClazz(), id.getName()));
}

根据参数个数>=元数决定搜索范围(0-maxAcceptIndex)

private static int maxAcceptIndex(MethodSignature[] methods, MethodIdentifier id) {int argsLength = id.getArgumentTypes().length;// binary searchint from = 0;int to = methods.length - 1;while (from <= to) {int index = (from + to) >>> 1;if (methods[index].getParameterTypes().length > argsLength) {to = index - 1;} else {if (index == methods.length - 1 ||methods[index + 1].getParameterTypes().length > argsLength) {return index;} else {from = index + 1;}}}return -1;
}

确定最特定方法

private static MethodSignature determine(MethodSignature[] overloading, MethodIdentifier id) {MethodSignatureDeterminer determiner = new MethodSignatureDeterminer();for (int index = maxAcceptIndex(overloading, id); index >= 0; --index) {determiner.accept(overloading[index], id);if (determiner.getCurrentPhase() == MethodSignatureDeterminer.Phase.FINISH) {break;}}return determiner.getMostSpecific();
}


3.根据属性名查找getter方法

虽然可在2的基础上实现这个功能,但是由于getter方法名及参数个数(0)的特殊性,以及getter方法调用频率较高,可作一定优化。

getter方法名:getXxx(普通),isXxx(布尔类型),xxx(布尔类型且属性名类似isXxx)

public class PropertyGetterLookup implements Lookup<ClassNamePair, Method> {
...private static List<String> getterNames(String name) {StringBuilder buffer = new StringBuilder(3 + name.length());buffer.append("get").append(name).setCharAt("get".length(), Character.toUpperCase(name.charAt(0)));String get = buffer.toString();buffer.setLength(0);buffer.append("is").append(name).setCharAt("is".length(), Character.toUpperCase(name.charAt(0)));String is = buffer.toString();return Arrays.asList(get, is, name);}
...
}

查找getter方法并选择

public Method find(ClassNamePair key) {return filterAndChoose(key.getClazz().getMethods(), getterNames(key.getName()));
}private static Method filterAndChoose(Method[] methods, List<String> names) {Method getter = null;int nameIndex = -1;for (Method method : methods) {int theIndex = names.indexOf(method.getName());if (theIndex >= 0 && method.getParameterTypes().length == 0) {if (theIndex == 0) {return method;} else {if (getter == null || theIndex < nameIndex) {getter = method;nameIndex = theIndex;}}}}return getter;
}


性能提升:

经测试,对FieldLookup,PropertyGetterLookup,OverloadingLookup使用缓存可以较好的提升性能,而对MethodLookup使用缓存性能提升较少,甚至可能出现性能降低的情况。 

通用查找缓存

public class CachedLookup<K, V> implements Lookup<K, V> {private final Lookup<K, V> lookup;private final Map<K, Future<V>> cache;private final ExecutorService executorService;public CachedLookup(Lookup<K, V> lookup, Map<K, Future<V>> cache, ExecutorService executorService) {this.lookup = lookup;this.cache = cache;this.executorService = executorService;}@Overridepublic V find(final K key) {Future<V> value = cache.get(key);if (value == null) {synchronized (cache) {value = cache.get(key);if (value == null) {value = executorService.submit(new Callable<V>() {@Overridepublic V call() throws Exception {return lookup.find(key);}});cache.put(key, value);}}}try {return value.get();} catch (Exception e) {return lookup.find(key);}}
}

简单LRU缓存

public class SimpleLRUCache<K, V> extends LinkedHashMap<K, V> {private final int threshold;public SimpleLRUCache(int threshold) {this(threshold, 0.75f);}public SimpleLRUCache(int threshold, float loadFactor) {super((int) (threshold / loadFactor) + 1, loadFactor, true);this.threshold = threshold;}@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > threshold;}
}

 
便捷方法:

public class Fields {private static final ExecutorService executorService = Executors.newCachedThreadPool();private static final Lookup<ClassNamePair, Field> fieldLookup = buildFieldLookup();private static final Lookup<ClassNamePair, Method> propertyGetterLookup = buildPropertyGetterLookup();private static Lookup<ClassNamePair, Field> buildFieldLookup() {return new CachedLookup<>(new FieldLookup(),new SimpleLRUCache<ClassNamePair, Future<Field>>(1000),executorService);}private static Lookup<ClassNamePair, Method> buildPropertyGetterLookup() {return new CachedLookup<>(new PropertyGetterLookup(),new SimpleLRUCache<ClassNamePair, Future<Method>>(1000),executorService);}public static Field getField(Class<?> cls, String name) {return fieldLookup.find(new ClassNamePair(cls, name));}public static Method getGetter(Class<?> cls, String name) {return propertyGetterLookup.find(new ClassNamePair(cls, name));}public static Object get(Object object, String name)throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {Method getter = propertyGetterLookup.find(new ClassNamePair(object.getClass(), name));if (getter != null) {return getter.invoke(object);}throw new NoSuchMethodException("Could not find getter for " +object.getClass().getName() + "." + name);}public static void set(Object object, String name, Object... value)throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {StringBuilder setter = new StringBuilder("set".length() + name.length());setter.append("set").append(name).setCharAt("set".length(), Character.toUpperCase(name.charAt(0)));Methods.invoke(object, setter.toString(), value);}public static Object directGet(Field field, Object object) {try {if (field.isAccessible()) {return field.get(object);} else {field.setAccessible(true);Object value = field.get(object);field.setAccessible(false);return value;}} catch (IllegalAccessException e) {// should never reach herethrow new RuntimeException(e);}}public static void directSet(Field field, Object object, Object value) {try {if (field.isAccessible()) {field.set(object, value);} else {field.setAccessible(true);field.set(object, value);field.setAccessible(false);}} catch (IllegalAccessException e) {// should never reach herethrow new RuntimeException(e);}}
}

public class Methods {private static final ExecutorService executorService = Executors.newCachedThreadPool();private static final Lookup<MethodIdentifier, Method> methodLookup = buildMethodLookup();private static Lookup<MethodIdentifier, Method> buildMethodLookup() {return new MethodLookup(buildOverloadingLookup());}private static Lookup<ClassNamePair, MethodSignature[]> buildOverloadingLookup() {return new CachedLookup<>(new OverloadingLookup(),new SimpleLRUCache<ClassNamePair, Future<MethodSignature[]>>(1000),executorService);}private static final Class<?>[] EMPTY_ARGUMENT_TYPES = new Class<?>[0];public static Class<?>[] getArgumentTypes(Object... args) {if (args.length == 0) {return EMPTY_ARGUMENT_TYPES;}Class<?>[] argTypes = new Class<?>[args.length];for (int i = 0; i < args.length; ++i) {argTypes[i] = args[i] == null ? null : args[i].getClass();}return argTypes;}public static Method getMethod(Class<?> cls, String name, Class<?>... argTypes) {return methodLookup.find(new MethodIdentifier(cls, name, argTypes));}public static Object invoke(Object object, String name, Object... args)throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {return invoke(object.getClass(), name, getArgumentTypes(args), object, args);}public static Object invokeStatic(Class<?> cls, String name, Object... args)throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {return invoke(cls, name, getArgumentTypes(args), null, args);}private static Object invoke(Class<?> cls, String name, Class<?>[] argTypes, Object object, Object... args)throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {Method method = getMethod(cls, name, argTypes);if (method != null) {return method.invoke(object, args);}throw new NoSuchMethodException(invokeToString(cls, name, args));}private static String invokeToString(Class<?> cls, String name, Object... args) {StringBuilder buffer = new StringBuilder();buffer.append(cls.getName());buffer.append('.');buffer.append(name);buffer.append('(');if (args.length > 0) {for (Object arg : args) {buffer.append(arg).append(',');}buffer.setLength(buffer.length() - 1);}buffer.append(')');return buffer.toString();}
}


简易性能测试:

Reflect Benchmark                                      
os name: Linux
os arch: i386
os version: 3.2.0-24-generic
java version: 1.7.0_02
jvm name: Java HotSpot(TM) Server VM
jvm version: 22.0-b10
arguments:-Didea.launcher.port=7532-Didea.launcher.bin.path=/home/canghailan/apps/idea-IC-111.69/bin-Dfile.encoding=UTF-8
times: 50000000 using: 26s
case                                                             total(ns)  per(ns) ratio    
EMPTY BENCHMARK CASE                                             56362      0       1        
user.getName()                                                   89515916   1       1,588.2  
Fields.get(user, "name")                                         2610483925 52      46,316.4 
Fields.directGet(Fields.getField(user.getClass(), "name"), user) 2948211600 58      52,308.5 
Methods.invoke(user, "getName")                                  5645685285 112     100,168.3
PropertyUtils.getSimpleProperty(user, "name")                    5097645621 101     90,444.7 
PropertyUtils.getProperty(user, "name")                          9721426876 194     172,481.9

 
完整代码:

http://www.oschina.net/code/snippet_116768_10408 

转载于:https://my.oschina.net/canghailan/blog/56219

http://www.jmfq.cn/news/5141665.html

相关文章:

  • appcms程序怎么做网站/网络营销做得比较成功的案例
  • 申请域名建立网站/电商运营主要做什么
  • 怎么给自己喜欢的人做网站/直通车推广技巧
  • wordpress 维基主题/南宁seo推广外包
  • 深圳pc端网站开发/搜索引擎营销的常见方式
  • 青羊区定制网站建设报价/网络营销策划推广公司
  • 江阴做网站/关键词的作用
  • 海尔公司的网站建设/厦门网站关键词推广
  • 编程和做网站有关系吗/百度网盘官网下载
  • 手机怎么制作网站教程/深圳网络推广培训学校
  • 做任务免费得晋江币网站/百度号码认证申诉平台
  • 2019建设摩托官方网站/宁波seo教程
  • 58网页版登录打开/长沙专业seo优化推荐
  • 洛阳洛龙区网站建设/网站的seo是什么意思
  • 长治政府网官网/优化关键词排名工具
  • 高邑网站建设/武汉seo招聘网
  • 行业顶级域名com/免费发布网站seo外链
  • 海口市住房和城乡建设局网站/海外推广渠道都有哪些
  • 网站的风格设计有哪些/sem优化策略
  • 西安优化网站技术/深圳百度推广代理
  • 网站做不做301/线上推广平台有哪些
  • 网站图表怎么做的/新闻网最新消息
  • 大网站设计/app数据分析软件
  • 顺义网站做的比较好的公司/壹起航网络推广的目标
  • 512内存做网站/互联网营销成功案例
  • 网站建设需要哪些东西/接广告赚钱的平台
  • w78企业网站后台怎么做/电商网站建设教程
  • 找聊城做网站/东莞网站排名提升
  • 电子商务网站面临的安全隐患/网站推广策划思路的内容
  • 公司企业网站建设的建站流程解析/拉新注册app拿佣金