001package net.gdface.utils; 002import static com.google.common.base.Preconditions.*; 003 004import java.lang.reflect.MalformedParameterizedTypeException; 005import java.lang.reflect.ParameterizedType; 006import java.lang.reflect.Type; 007import java.lang.reflect.TypeVariable; 008import java.util.Arrays; 009 010import com.google.common.base.Function; 011import com.google.common.collect.Lists; 012import com.google.common.reflect.TypeToken; 013 014/** 015 * 基于jdk1.7ä¸ {@link sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl}实现<br> 016 * ä¿®æ£åŽŸç‰ˆæœ¬ä¸toString方法错误 017 * @author guyadong 018 * 019 */ 020@SuppressWarnings("restriction") 021public class ParameterizedTypeImpl implements ParameterizedType { 022 private Type[] actualTypeArguments; 023 private Class<?> rawType; 024 private Type ownerType; 025 public static final Function<Type,Type> WRAPPER = new Function<Type,Type>(){ 026 027 @Override 028 public Type apply(Type input) { 029 if(input instanceof ParameterizedTypeImpl){ 030 return input; 031 }else if(input instanceof ParameterizedType){ 032 return new ParameterizedTypeImpl((ParameterizedType)input); 033 } 034 return input; 035 }}; 036 /** 037 * æž„é€ æ–¹æ³• 038 * 基于已有{@link ParameterizedType}å®žä¾‹æž„é€ ä¸€ä¸ªæ–°å¯¹è±¡ 039 * @param source ä¸å¯ä¸º{@link null} 040 */ 041 public ParameterizedTypeImpl(ParameterizedType source){ 042 this(TypeToken.of(checkNotNull(source)).getRawType(),source.getActualTypeArguments(),source.getOwnerType()); 043 } 044 public ParameterizedTypeImpl(Class<?> rawType, Type[] actualTypeArguments, Type ownerType) { 045 checkArgument(null !=rawType && null !=actualTypeArguments); 046 this.actualTypeArguments = Lists.transform(Lists.newArrayList(actualTypeArguments),WRAPPER).toArray(new Type[0]); 047 this.rawType = rawType; 048 this.ownerType = WRAPPER.apply(ownerType != null ? ownerType : rawType.getDeclaringClass()); 049 this.validateConstructorArguments(); 050 } 051 052 private void validateConstructorArguments() { 053 TypeVariable<?>[] formals = this.rawType.getTypeParameters(); 054 if (formals.length != this.actualTypeArguments.length) { 055 throw new MalformedParameterizedTypeException(); 056 } 057 for (int i = 0; i < this.actualTypeArguments.length; ++i) { 058 } 059 } 060 061 @Override 062 public Type[] getActualTypeArguments() { 063 return (Type[]) this.actualTypeArguments.clone(); 064 } 065 066 @Override 067 public Class<?> getRawType() { 068 return this.rawType; 069 } 070 071 @Override 072 public Type getOwnerType() { 073 return this.ownerType; 074 } 075 076 @Override 077 public boolean equals(Object o) { 078 if (o instanceof ParameterizedType) { 079 ParameterizedType that = (ParameterizedType) o; 080 if (this == that) { 081 return true; 082 } 083 Type thatOwner = that.getOwnerType(); 084 Type thatRawType = that.getRawType(); 085 return (this.ownerType == null ? thatOwner == null : this.ownerType.equals(thatOwner)) 086 && (this.rawType == null ? thatRawType == null : this.rawType.equals(thatRawType)) 087 && Arrays.equals(this.actualTypeArguments, that.getActualTypeArguments()); 088 } 089 return false; 090 } 091 092 public int hashCode() { 093 return Arrays.hashCode(this.actualTypeArguments) ^ (this.ownerType == null ? 0 : this.ownerType.hashCode()) 094 ^ (this.rawType == null ? 0 : this.rawType.hashCode()); 095 } 096 097 public String toString() { 098 StringBuilder sb = new StringBuilder(); 099 if (this.ownerType != null) { 100 if (this.ownerType instanceof Class) { 101 sb.append(((Class<?>) this.ownerType).getName()); 102 } else { 103 sb.append(this.ownerType.toString()); 104 } 105 sb.append("."); 106 if (this.ownerType instanceof ParameterizedTypeImpl) { 107 sb.append(this.rawType.getName() 108 .replace(((ParameterizedTypeImpl) this.ownerType).rawType.getName() + "$", "")); 109 } else { 110 sb.append(this.rawType.getSimpleName()); 111 } 112 } else { 113 sb.append(this.rawType.getName()); 114 } 115 if (this.actualTypeArguments != null && this.actualTypeArguments.length > 0) { 116 sb.append("<"); 117 boolean first = true; 118 for (Type t : this.actualTypeArguments) { 119 if (!first) { 120 sb.append(", "); 121 } 122 if (t instanceof Class) { 123 sb.append(((Class<?>) t).getName()); 124 } else { 125 sb.append(t.toString()); 126 } 127 first = false; 128 } 129 sb.append(">"); 130 } 131 return sb.toString(); 132 } 133 /** 134 * 将当å‰å¯¹è±¡çš„ç±»åž‹å‚æ•°ä¸ä¸º{@code oldType}çš„å…ƒç´ æ›¿æ¢ä¸º{@code newType} 135 * @param oldType ä¸å¯ä¸º{@code null} 136 * @param newType ä¸å¯ä¸º{@code null} 137 * @return 138 */ 139 public ParameterizedType transform(Type oldType,Type newType ){ 140 checkNotNull(oldType); 141 checkNotNull(newType); 142 Type[] typeArgs = getActualTypeArguments(); 143 for(int i =0 ;i<typeArgs.length;++i){ 144 if(typeArgs[i]==oldType) 145 typeArgs[i] = newType; 146 } 147 return new ParameterizedTypeImpl(TypeToken.of(this).getRawType(), typeArgs, getOwnerType()); 148 } 149 /** 150 * ç”¨æŒ‡å®šçš„ç±»åž‹å‚æ•°æ›¿æ¢å½“å‰å¯¹è±¡çš„ç±»åž‹å‚æ•°<br> 151 * æ–°å‚æ•°çš„个数与当å‰å¯¹è±¡çš„ç±»åž‹å‚æ•°ä¸ªæ•°å¿…须一致, 152 * å¦‚æžœæ–°å‚æ•°æ•°ç»„ä¸å…ƒç´ 为{@code null}åˆ™å¯¹åº”çš„å‚æ•°ä¸ä¼šè¢«æ›¿æ¢ 153 * @param newTypeArguments 154 * @return 155 */ 156 public ParameterizedType transform(Type[] newTypeArguments){ 157 checkNotNull(newTypeArguments); 158 Type[] typeArgs = getActualTypeArguments(); 159 checkArgument(newTypeArguments.length == typeArgs.length ); 160 for(int i=0;i<typeArgs.length;++i){ 161 if(null != newTypeArguments[i]){ 162 typeArgs[i] = newTypeArguments[i]; 163 } 164 } 165 return new ParameterizedTypeImpl(TypeToken.of(this).getRawType(), typeArgs, getOwnerType()); 166 } 167}