}
ParameterizedTypeImpl parameterizedTypeInfo = buildingCache.getParameterizedType(type);
if (parameterizedTypeInfo == null) {
RawTypeInfo rawType = buildRawType((Class<?>) type.getRawType(), buildingCache);
parameterizedTypeInfo = new ParameterizedTypeImpl(rawType);
buildingCache.setParameterizedType(type, parameterizedTypeInfo);
// ȡ��actual type arguments
TypeInfo[] args = buildTypes(type.getActualTypeArguments(), buildingCache);
// ����wildcard��upper boundsΪ��Ӧvar��upper bounds
// ���磬varΪ<T extends Number>����wildcardδָ��upper bounds����ô����wildcard��upper boundsΪNumber
for (int i = 0; i < args.length; i++) {
TypeInfo arg = args[i];
if (arg instanceof WildcardTypeInfo && ((WildcardTypeInfo) arg).isUnknown()) {
TypeVariable<?> var = rawType.getRawType().getTypeParameters()[i];
TypeInfo[] upperBounds = buildTypes(var.getBounds(), buildingCache);
args[i] = new UnknownWildcardTypeImpl((WildcardTypeInfo) arg, upperBounds);
}
}