001package net.gdface.utils; 002 003import static com.google.common.base.Preconditions.checkArgument; 004 005import java.lang.reflect.GenericArrayType; 006import java.lang.reflect.ParameterizedType; 007import java.lang.reflect.Type; 008import java.lang.reflect.TypeVariable; 009import java.lang.reflect.WildcardType; 010import java.util.List; 011import java.util.Map; 012import java.util.Set; 013 014import com.google.common.reflect.TypeParameter; 015import com.google.common.reflect.TypeToken; 016 017/** 018 * 对象类型相关工具 019 * @author guyadong 020 * 021 */ 022public class TypeUtils { 023 024 public TypeUtils() { 025 } 026 public static interface Action{ 027 void doClass(Class<?> type); 028 } 029 public static void traverseTypes(Type type,Action action){ 030 checkArgument(null !=action,"action is null"); 031 if(type instanceof Class<?>){ 032 action.doClass((Class<?>) type); 033 }else if( type instanceof ParameterizedType){ 034 ParameterizedType paramType = (ParameterizedType)type; 035 Type rawType = paramType.getRawType(); 036 Type[] typeArgs = paramType.getActualTypeArguments(); 037 traverseTypes(rawType,action); 038 for(Type arg:typeArgs){ 039 traverseTypes(arg,action); 040 } 041 }else if (type instanceof GenericArrayType) { 042 traverseTypes(((GenericArrayType) type).getGenericComponentType(),action); 043 } else if (type instanceof TypeVariable) { 044 for (Type t : ((TypeVariable<?>) type).getBounds()) { 045 traverseTypes(t,action); 046 } 047 } else if (type instanceof WildcardType) { 048 for (Type t : ((WildcardType) type).getLowerBounds()) { 049 traverseTypes(t,action); 050 } 051 for (Type t : ((WildcardType) type).getUpperBounds()) { 052 traverseTypes(t,action); 053 } 054 } else{ 055 throw new IllegalArgumentException(String.format("not allow type %s", type.toString())); 056 } 057 } 058 @SuppressWarnings("serial") 059 public static <K, V> TypeToken<Map<K, V>> mapToken(TypeToken<K> keyToken, TypeToken<V> valueToken) { 060 return new TypeToken<Map<K, V>>() {} 061 .where(new TypeParameter<K>() {}, keyToken) 062 .where(new TypeParameter<V>() {}, valueToken); 063 } 064 @SuppressWarnings("serial") 065 public static <T> TypeToken<List<T>> listToken(TypeToken<T> keyToken) { 066 return new TypeToken<List<T>>() {} 067 .where(new TypeParameter<T>() {}, keyToken); 068 } 069 @SuppressWarnings("serial") 070 public static <T> TypeToken<Set<T>> setToken(TypeToken<T> keyToken) { 071 return new TypeToken<Set<T>>() {} 072 .where(new TypeParameter<T>() {}, keyToken); 073 } 074 075}