001package net.gdface.utils; 002 003import static com.google.common.base.Preconditions.*; 004import java.lang.reflect.Constructor; 005import java.lang.reflect.Field; 006import java.lang.reflect.Method; 007import java.lang.reflect.Modifier; 008import java.util.Collections; 009import java.util.LinkedHashMap; 010import java.util.Map; 011 012import com.google.common.base.MoreObjects; 013import com.google.common.base.Strings; 014import com.google.common.base.Throwables; 015import com.google.common.collect.ForwardingMap; 016 017/** 018 * @author guyadong 019 * 020 */ 021public class ReflectionUtils { 022 public static final String PROP_CLASSNAME = "className"; 023 public static final String PROP_STATICMETHODNAME = "staticMethodName"; 024 public static final String PROP_PARAMETERTYPES = "parameterTypes"; 025 public static final String PROP_CONSTRUCTORARGS = "constructorArgs"; 026 public static final String PROP_CONSTRUCTORPARAMS = "constructorParams"; 027 private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0]; 028 private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; 029 public ReflectionUtils() { 030 } 031 private static class ParameterMap extends ForwardingMap<String,Object>{ 032 private final Map<String, Object> delegate; 033 public ParameterMap(Map<String, Object> delegate) { 034 super(); 035 if(null == delegate){ 036 this.delegate = Collections.emptyMap(); 037 }else{ 038 this.delegate = delegate; 039 } 040 } 041 @Override 042 protected Map<String, Object> delegate() { 043 return delegate; 044 } 045 @SuppressWarnings("unchecked") 046 public final <T> T of(String key,T defaultValue){ 047 checkArgument(null != key); 048 Object value = delegate.get(key); 049 try{ 050 return null == value ? defaultValue: (T) value; 051 }catch(ClassCastException e){ 052 throw new IllegalArgumentException("invalid parameter: " + key + ",caused by " + e.getMessage()); 053 } 054 } 055 public final <T> T of(String key){ 056 return of(key,null); 057 } 058 } 059 @SuppressWarnings("unchecked") 060 public static <T> Class<? extends T> getInstanceClass(Class<T> superClass,String instanceClassName) 061 throws ClassNotFoundException{ 062 checkArgument(null != superClass && !Strings.isNullOrEmpty(instanceClassName)); 063 Class<?> instanceClass = (Class<?>) Class.forName(instanceClassName); 064 checkInstanceClass(superClass,instanceClass); 065 return (Class<? extends T>)instanceClass; 066 } 067 public static <T> T getInstance(Class<T> superClass,Map<String,Object> params) 068 throws NoSuchMethodException, ClassNotFoundException{ 069 ParameterMap paramMap = new ParameterMap(params); 070 String clazzName = paramMap.of(PROP_CLASSNAME); 071 Class<? extends T> instanceClass = getInstanceClass(superClass,clazzName); 072 String staticMethodName =paramMap.of(PROP_STATICMETHODNAME); 073 if(null != staticMethodName){ 074 try{ 075 return getInstanceByStaticMethod(superClass,instanceClass,staticMethodName); 076 }catch(NoSuchMethodException e){ 077 // 找ä¸åˆ°é™æ€æ–¹æ³•则å°è¯•ç”¨æž„é€ æ–¹æ³•åˆ›å»ºå®žä¾‹ 078 } 079 } 080 if(paramMap.containsKey(PROP_CONSTRUCTORPARAMS)){ 081 LinkedHashMap<Class<?>,Object> constructorParams = paramMap.of(PROP_CONSTRUCTORPARAMS); 082 return getInstanceByConstructor(superClass,instanceClass,constructorParams); 083 }else{ 084 Class<?>[] parameterTypes = paramMap.of(PROP_PARAMETERTYPES); 085 Object[] ctorArgs = paramMap.of(PROP_CONSTRUCTORARGS); 086 return getInstanceByConstructor(superClass,instanceClass,parameterTypes,ctorArgs); 087 } 088 } 089 private static void checkInstanceClass(Class<?> superClass,Class<?> instanceClass){ 090 checkArgument(null != superClass && null != instanceClass); 091 checkArgument(!instanceClass.isInterface() && superClass.isAssignableFrom(instanceClass), 092 "%s not a implemenation of %s",instanceClass.getName(),superClass.getSimpleName()); 093 checkArgument(!Modifier.isAbstract(instanceClass.getModifiers()), 094 "%s is abstract class",instanceClass.getName()); 095 checkArgument(Modifier.isStatic(instanceClass.getModifiers()) || null == instanceClass.getDeclaringClass(), 096 "%s is not static class",instanceClass.getName()); 097 } 098 public static <T> T getInstanceByConstructor(Class<T> superClass,Class<? extends T> instanceClass,Class<?>[] parameterTypes,Object[] constructorArgs) 099 throws NoSuchMethodException{ 100 checkInstanceClass(superClass,instanceClass); 101 parameterTypes = MoreObjects.firstNonNull(parameterTypes, EMPTY_CLASS_ARRAY); 102 constructorArgs = MoreObjects.firstNonNull(constructorArgs, EMPTY_OBJECT_ARRAY); 103 checkArgument(parameterTypes.length == constructorArgs.length); 104 try{ 105 Constructor<? extends T> ctor = instanceClass.getConstructor(parameterTypes); 106 try { 107 return ctor.newInstance(constructorArgs); 108 } catch (Exception e) { 109 Throwables.throwIfUnchecked(e); 110 throw new RuntimeException(e); 111 } 112 } finally{} 113 } 114 public static <T> T getInstanceByConstructor(Class<T> superClass,Class<? extends T> instanceClass,LinkedHashMap<Class<?>,Object> constructorParams) 115 throws NoSuchMethodException{ 116 checkInstanceClass(superClass,instanceClass); 117 constructorParams = MoreObjects.firstNonNull(constructorParams, new LinkedHashMap<Class<?>,Object>()); 118 Class<?>[] parameterTypes = constructorParams.keySet().toArray(new Class<?>[constructorParams.size()]); 119 Object[] initargs = constructorParams.values().toArray(new Object[constructorParams.size()]); 120 Constructor<? extends T> ctor = instanceClass.getConstructor(parameterTypes); 121 try { 122 return ctor.newInstance(initargs); 123 } catch (Exception e) { 124 Throwables.throwIfUnchecked(e); 125 throw new RuntimeException(e); 126 } 127 } 128 @SuppressWarnings("unchecked") 129 public static <T> T getInstanceByStaticMethod(Class<T> superClass,Class<? extends T> instanceClass,String staticMethodName) 130 throws NoSuchMethodException{ 131 checkArgument(!Strings.isNullOrEmpty(staticMethodName)); 132 checkInstanceClass(superClass,instanceClass); 133 try { 134 Method method = instanceClass.getMethod(staticMethodName); 135 checkArgument(Modifier.isStatic(method.getModifiers()),"%s is not a static method",method.toString()); 136 checkArgument(superClass.isAssignableFrom(method.getReturnType()),"unexpect return type %s",method.getReturnType().toString()); 137 try{ 138 return (T) method.invoke(null); 139 }catch(ClassCastException e){ 140 throw new IllegalArgumentException( 141 String.format("invalid return type of static method %s caused by %s",method.toString(),e.getMessage())); 142 } 143 } catch(NoSuchMethodException e){ 144 throw e; 145 }catch (Exception e) { 146 Throwables.throwIfUnchecked(e); 147 throw new RuntimeException(e); 148 } 149 } 150 /** 151 * å射获å–{@code object}çš„ç§æœ‰æˆå‘˜ 152 * @param object 153 * @param name 154 * @return æˆå‘˜å¯¹è±¡ 155 */ 156 @SuppressWarnings("unchecked") 157 public static <T> T valueOfField(Object object,String name){ 158 try { 159 Field field = checkNotNull(object,"object is null").getClass().getDeclaredField(checkNotNull(name,"name is null")); 160 field.setAccessible(true); 161 return (T) field.get(object); 162 } catch (Exception e) { 163 Throwables.throwIfUnchecked(e); 164 throw new RuntimeException(e); 165 } 166 } 167}