下面列出了java.lang.reflect.WildcardType#getUpperBounds ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns a type that is functionally equal but not necessarily equal according to {@link
* Object#equals(Object) Object.equals()}.
*/
public static Type canonicalize(Type type) {
if (type instanceof Class) {
Class<?> c = (Class<?>) type;
return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c;
} else if (type instanceof ParameterizedType) {
if (type instanceof ParameterizedTypeImpl) return type;
ParameterizedType p = (ParameterizedType) type;
return new ParameterizedTypeImpl(p.getOwnerType(),
p.getRawType(), p.getActualTypeArguments());
} else if (type instanceof GenericArrayType) {
if (type instanceof GenericArrayTypeImpl) return type;
GenericArrayType g = (GenericArrayType) type;
return new GenericArrayTypeImpl(g.getGenericComponentType());
} else if (type instanceof WildcardType) {
if (type instanceof WildcardTypeImpl) return type;
WildcardType w = (WildcardType) type;
return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
} else {
return type; // This type is unsupported!
}
}
/**
* Returns a type that is functionally equal but not necessarily equal according to {@link
* Object#equals(Object) Object.equals()}.
*/
static Type canonicalize(Type type) {
if (type instanceof Class) {
Class<?> c = (Class<?>) type;
return c.isArray() ? new GenericArrayTypeImpl(c.getComponentType()) : c;
} else if (type instanceof ParameterizedType) {
if (type instanceof ParameterizedTypeImpl) return type;
ParameterizedType p = (ParameterizedType) type;
return new ParameterizedTypeImpl(
p.getOwnerType(), p.getRawType(), p.getActualTypeArguments());
} else if (type instanceof GenericArrayType) {
if (type instanceof GenericArrayTypeImpl) return type;
GenericArrayType g = (GenericArrayType) type;
return new GenericArrayTypeImpl(g.getGenericComponentType());
} else if (type instanceof WildcardType) {
if (type instanceof WildcardTypeImpl) return type;
WildcardType w = (WildcardType) type;
return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
} else {
return type; // This type is unsupported!
}
}
private void checkLowerBoundedParameter(Method method) {
Type genericParameterType = method.getGenericParameterTypes()[0];
assertInstanceOf(ParameterizedType.class, genericParameterType);
ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
assertLenghtOne(actualTypeArguments);
assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
assertEquals("? super T", wildcardType.toString());
assertEquals("? super T", wildcardType.getTypeName());
Type[] lowerBounds = wildcardType.getLowerBounds();
assertLenghtOne(lowerBounds);
Type lowerBound = lowerBounds[0];
assertEquals(getTypeParameter(method), lowerBound);
Type[] upperBounds = wildcardType.getUpperBounds();
assertEquals(Object.class, upperBounds[0]);
}
private static Class<?> getGenericClass(ParameterizedType parameterizedType, int i) {
Type genericClass = null;
try {
genericClass = parameterizedType.getActualTypeArguments()[i];
} catch (Exception e) {
return null;
}
if (genericClass instanceof ParameterizedType) {
return (Class) ((ParameterizedType) genericClass).getRawType();
} else if (genericClass instanceof GenericArrayType) {
return (Class<?>) ((GenericArrayType) genericClass).getGenericComponentType();
} else if (genericClass instanceof TypeVariable) {
return getClass(((TypeVariable) genericClass).getBounds()[0], 0);
} else if (genericClass instanceof WildcardType) {
WildcardType wuleType = (WildcardType) genericClass;
if (null != wuleType.getUpperBounds()[0]) {
return getClass(wuleType.getUpperBounds()[0], 0);
} else {
return getClass(wuleType.getLowerBounds()[0], 0);
}
} else {
return (Class<?>) genericClass;
}
}
@Override
Class<?> toRawType(Type type, Class<?> implClass) {
WildcardType wType = (WildcardType) type;
Type[] lowerTypes = wType.getLowerBounds();
if (lowerTypes.length > 0) {
return getRawType(lowerTypes[0], implClass);
}
Type[] upperTypes = wType.getUpperBounds();
if (upperTypes.length != 0) {
return getRawType(upperTypes[0], implClass);
}
return Object.class;
}
private static JavaType constructWildCardType(WildcardType type) {
// For our simplified type system we can safely replace upper bounds
// When registering a transformer to type ? extends SomeType the
// transformer is guaranteed to produce an object that is an instance of
// SomeType.
// When transforming a data table to ? extends SomeType a transformer
// that produces SomeType is sufficient.
// This will result in ambiguity between a transformers for SomeType
// and transformers for ? extends SomeType but that seems reasonable and
// might be resolved by using a more specific producer.
Type[] upperBounds = type.getUpperBounds();
if (upperBounds.length > 0) {
// Not possible in Java. Scala?
if (upperBounds.length > 1) {
throw new IllegalArgumentException("Type contained more then upper lower bound " + type + ". Types may only have a single upper bound.");
}
return constructType(upperBounds[0]);
}
// We'll treat lower bounds as is.
return new OtherType(type);
}
public static Class<?> getCollectionItemClass(Type fieldType){
if(fieldType instanceof ParameterizedType){
Class<?> itemClass;
Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
if(actualTypeArgument instanceof WildcardType){
WildcardType wildcardType = (WildcardType) actualTypeArgument;
Type[] upperBounds = wildcardType.getUpperBounds();
if(upperBounds.length == 1){
actualTypeArgument = upperBounds[0];
}
}
if(actualTypeArgument instanceof Class){
itemClass = (Class<?>) actualTypeArgument;
if(!Modifier.isPublic(itemClass.getModifiers())){
throw new JSONException("can not create ASMParser");
}
} else{
throw new JSONException("can not create ASMParser");
}
return itemClass;
}
return Object.class;
}
/**
* Get a {@link WildcardBounds} instance for the specified type, returning
* {@code null} if the specified type cannot be resolved to a {@link WildcardType}.
* @param type the source type
* @return a {@link WildcardBounds} instance or {@code null}
*/
public static WildcardBounds get(ResolvableType type) {
ResolvableType resolveToWildcard = type;
while (!(resolveToWildcard.getType() instanceof WildcardType)) {
if (resolveToWildcard == NONE) {
return null;
}
resolveToWildcard = resolveToWildcard.resolveType();
}
WildcardType wildcardType = (WildcardType) resolveToWildcard.type;
Kind boundsType = (wildcardType.getLowerBounds().length > 0 ? Kind.LOWER : Kind.UPPER);
Type[] bounds = (boundsType == Kind.UPPER ? wildcardType.getUpperBounds() : wildcardType.getLowerBounds());
ResolvableType[] resolvableBounds = new ResolvableType[bounds.length];
for (int i = 0; i < bounds.length; i++) {
resolvableBounds[i] = ResolvableType.forType(bounds[i], type.variableResolver);
}
return new WildcardBounds(boundsType, resolvableBounds);
}
public static Type canonicalize(Type type)
{
if (type instanceof Class)
{
type = (Class)type;
if (type.isArray())
{
type = new a(canonicalize(((Type) (type.getComponentType()))));
}
} else
{
if (type instanceof ParameterizedType)
{
ParameterizedType parameterizedtype = (ParameterizedType)type;
return new b(parameterizedtype.getOwnerType(), parameterizedtype.getRawType(), parameterizedtype.getActualTypeArguments());
}
if (type instanceof GenericArrayType)
{
return new a(((GenericArrayType)type).getGenericComponentType());
}
if (type instanceof WildcardType)
{
WildcardType wildcardtype = (WildcardType)type;
return new c(wildcardtype.getUpperBounds(), wildcardtype.getLowerBounds());
}
}
return type;
}
/**
* Returns a type that is functionally equal but not necessarily equal
* according to {@link Object#equals(Object) Object.equals()}.
*/
public static Type canonicalize(Type type) {
if (type instanceof ParameterizedTypeImpl
|| type instanceof GenericArrayTypeImpl
|| type instanceof WildcardTypeImpl) {
return type;
} else if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType) type;
return new ParameterizedTypeImpl(p.getOwnerType(),
p.getRawType(), p.getActualTypeArguments());
} else if (type instanceof GenericArrayType) {
GenericArrayType g = (GenericArrayType) type;
return new GenericArrayTypeImpl(g.getGenericComponentType());
} else if (type instanceof Class && ((Class<?>) type).isArray()) {
Class<?> c = (Class<?>) type;
return new GenericArrayTypeImpl(c.getComponentType());
} else if (type instanceof WildcardType) {
WildcardType w = (WildcardType) type;
return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
} else {
// type is either serializable as-is or unsupported
return type;
}
}
/**
* Determine whether the underlying type represents a wildcard
* without specific bounds (i.e., equal to {@code ? extends Object}).
*/
private boolean isWildcardWithoutBounds() {
if (this.type instanceof WildcardType) {
WildcardType wt = (WildcardType) this.type;
if (wt.getLowerBounds().length == 0) {
Type[] upperBounds = wt.getUpperBounds();
if (upperBounds.length == 0 || (upperBounds.length == 1 && Object.class == upperBounds[0])) {
return true;
}
}
}
return false;
}
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
// TODO check if GSON does caching of the created TypeAdapter for the given type
// extra caching could be added in this layer if there is only one polymorphic type
// adapter for the whole hierarchy
// https://google.github.io/gson/apidocs/com/google/gson/TypeAdapterFactory.html
// If a factory cannot support a given type, it must return null when that type is passed to create(com.google.gson.Gson, com.google.gson.reflect.TypeToken<T>)
if (type.getType() instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type.getType();
Type[] upperBounds = wildcardType.getUpperBounds();
if (upperBounds!=null && upperBounds.length==1) {
type = (TypeToken<T>) TypeToken.get(upperBounds[0]);
} else {
throw new RuntimeException("Unsupported wildcard type: "+type);
}
}
if (matchingTypes.contains(type)) {
if (typeAdapter==null) {
typeAdapter = new PolymorphicTypeAdapter<T>(type, this, gson);
}
return (TypeAdapter<T>) this.typeAdapter;
}
return null;
}
@Override
public Type[] getActualTypeArguments() {
final Type[] resolvedTypes = new Type[this.m_pType.getActualTypeArguments().length];
for (int i = 0; i < this.m_pType.getActualTypeArguments().length; i++) {
final Type actualType = this.m_pType.getActualTypeArguments()[i];
if (actualType instanceof WildcardType) {
final WildcardType actualWildcardType = (WildcardType) actualType;
final Type resolvedType = new WildcardType() {
@Override
public Type[] getUpperBounds() {
final Type[] resolvedUpperBounds = new Type[actualWildcardType.getUpperBounds().length];
for (int j = 0; j < actualWildcardType.getUpperBounds().length; j++) {
resolvedUpperBounds[j] = m_typeVariables.get(((TypeVariable<?>) actualWildcardType.getUpperBounds()[j]).getName());
}
return resolvedUpperBounds;
}
@Override
public Type[] getLowerBounds() {
final Type[] resolvedLowerBounds = new Type[actualWildcardType.getLowerBounds().length];
for (int j = 0; j < actualWildcardType.getLowerBounds().length; j++) {
resolvedLowerBounds[j] = m_typeVariables.get(((TypeVariable<?>) actualWildcardType.getLowerBounds()[j]).getName());
}
return resolvedLowerBounds;
}
};
resolvedTypes[i] = resolvedType;
} else {
throw new UnsupportedOperationException("Currently only WildcardType is supported");
}
}
return resolvedTypes;
}
/**
* Finds the Type value of the given wildcard type, using recursiveBounds to
* limit the recursion.
*
* @param var
* @param recursiveBounds
*
* @return the resolved Type instance
*/
public static <T> Type<T> limitedValueOf(final WildcardType var,
final Set<java.lang.reflect.Type> recursiveBounds) {
Set<Type<?>> bounds = new HashSet<Type<?>>(var.getUpperBounds().length + var.getLowerBounds().length);
for (int i = 0, len = var.getUpperBounds().length; i < len; ++i) {
bounds.add(limitedValueOf(var.getUpperBounds()[i], recursiveBounds));
}
for (int i = 0, len = var.getLowerBounds().length; i < len; ++i) {
bounds.add(limitedValueOf(var.getLowerBounds()[i], recursiveBounds));
}
return (Type<T>) refineBounds(bounds);
}
Type capture(Type type) {
checkNotNull(type);
if (type instanceof Class) {
return type;
}
if (type instanceof TypeVariable) {
return type;
}
if (type instanceof GenericArrayType) {
GenericArrayType arrayType = (GenericArrayType) type;
return Types.newArrayType(capture(arrayType.getGenericComponentType()));
}
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
return Types.newParameterizedTypeWithOwner(captureNullable(parameterizedType.getOwnerType()), (Class<?>) parameterizedType.getRawType(), capture(parameterizedType.getActualTypeArguments()));
}
if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
Type[] lowerBounds = wildcardType.getLowerBounds();
if (lowerBounds.length == 0) { // ? extends something changes to capture-of
Type[] upperBounds = wildcardType.getUpperBounds();
String name =
"capture#" + id.incrementAndGet() + "-of ? extends "
+ Joiner.on('&').join(upperBounds);
return Types.newArtificialTypeVariable(WildcardCapturer.class, name, wildcardType.getUpperBounds());
} else {
// TODO(benyu): handle ? super T somehow.
return type;
}
}
throw new AssertionError("must have been one of the known types");
}
public static ArrayList<Type> extracQualifiedGenTypes(ParameterizedType asParType, Map<String, GenericType> nameToGenericMap, boolean dontSetupInterfaceGenerics){
java.lang.reflect.Type[] parTypes = asParType.getActualTypeArguments();
ArrayList<Type> QualifiedgenTypes = new ArrayList<Type>(parTypes.length);
for( java.lang.reflect.Type partype : parTypes ){
//TODO: cater for all of these: GenericArrayType
//so these todo: GenericArrayType, ParameterizedType
//System.err.println("gens: " + partype);
if(partype instanceof TypeVariable){//generic
//String genParName = (((TypeVariable<?>)partype).getName());
//QualifiedgenTypes.add(nameToGenericMap.get(genParName));
QualifiedgenTypes.add(convertGenType(partype, nameToGenericMap, dontSetupInterfaceGenerics));
}
else if (partype instanceof WildcardType){
WildcardType wc = (WildcardType)partype;
java.lang.reflect.Type[] bound = wc.getLowerBounds();
boolean hasLower = bound != null && bound.length!=0;
if(!hasLower){
bound = wc.getUpperBounds();
}
Type tt = convertGenType(bound[0], nameToGenericMap, dontSetupInterfaceGenerics);
tt = tt==null?null:(Type)tt.copy();//why would tt be null?
if(!hasLower && tt.equals(ScopeAndTypeChecker.const_object)){
if(tt instanceof NamedType){
((NamedType)tt).isWildCardAny = true;
}
if(tt instanceof GenericType){
((GenericType)tt).isWildcard=true;
}
}else{
if(null == wc.getUpperBounds() && null == wc.getLowerBounds()){//ArrayList<?>
if(tt instanceof NamedType){
((NamedType)tt).isWildCardAny = true;
}
if(tt instanceof GenericType){
((GenericType)tt).isWildcard=true;
}
}
else if(tt != null){//ArrayList<? extends Number>
tt.setInOutGenModifier(hasLower?InoutGenericModifier.IN:InoutGenericModifier.OUT);
/*if(tt instanceof NamedType){
((NamedType)tt).isWildCardAny = true;
}
if(tt instanceof GenericType){
((GenericType)tt).isWildcard=true;
}*/
}
}
QualifiedgenTypes.add(tt);
}
else if(partype instanceof Class<?>){
QualifiedgenTypes.add(convertGenType(partype, nameToGenericMap, dontSetupInterfaceGenerics));
//dontSetupInterfaceGenerics - prevents infinite loop with Int -> Comparable<Int> which gets expanded forever
}
else if(partype instanceof ParameterizedType){
QualifiedgenTypes.add(convertGenType(partype, nameToGenericMap, dontSetupInterfaceGenerics));
}
else if(partype instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType)partype;
QualifiedgenTypes.add(convertGenType(gat.getGenericComponentType(), nameToGenericMap, dontSetupInterfaceGenerics));
}else{
throw new RuntimeException("Unexpected Parameterized type in convertGenType: " + partype);
}
}
return QualifiedgenTypes;
}
/**
* Tests if a generic type (may be <?>, <? extends {required}>
* or <? super {required}>) is compatible with the required one.
* TODO: Should be moved to an utility class
* @param required the required class the generic type MUST BE compatible with
* @param genericType the required class
* @return if the generic type is compatible with the required class
*/
public static boolean testType(Class<?> required, Type type) {
//for the examples let assume that a Set is the raw type and the
//requested generic type is a Representation with the following class
//hierarchy:
// Object
// -> Representation
// -> RdfRepresentation
// -> InMemoryRepresentation
// -> InputStream
// -> Collection<T>
boolean typeOK = false;
if(type instanceof Class<?>){
typeOK = required.isAssignableFrom((Class<?>) type);
type = ((Class<?>)type).getGenericSuperclass();
} else if(type instanceof WildcardType){
//In cases <? super {class}>, <? extends {class}, <?>
WildcardType wildcardSetType = (WildcardType) type;
if(wildcardSetType.getLowerBounds().length > 0){
Type lowerBound = wildcardSetType.getLowerBounds()[0];
//OK
// Set<? super RdfRepresentation>
// Set<? super Representation>
//NOT OK
// Set<? super InputStream>
// Set<? super Collection<Representation>>
typeOK = lowerBound instanceof Class<?> &&
required.isAssignableFrom((Class<?>)lowerBound);
} else if (wildcardSetType.getUpperBounds().length > 0){
Type upperBound = wildcardSetType.getUpperBounds()[0];
//OK
// Set<? extends Representation>
// Set<? extends Object>
//NOT OK
// Set<? extends RdfRepresentation>
// Set<? extends InputStream>
// Set<? extends Collection<Representation>
typeOK = upperBound instanceof Class<?> &&
((Class<?>)upperBound).isAssignableFrom(required);
} else { //no upper nor lower bound
// Set<?>
typeOK = true;
}
} else if(required.isArray() && type instanceof GenericArrayType){
//In case the required type is an array we need also to support
//possible generic Array specifications
GenericArrayType arrayType = (GenericArrayType)type;
typeOK = testType(required.getComponentType(), arrayType.getGenericComponentType());
} else if(type instanceof ParameterizedType){
ParameterizedType pType = ((ParameterizedType)type);
typeOK = pType.getRawType() instanceof Class<?> &&
required.isAssignableFrom((Class<?>)pType.getRawType());
type = null;
} else {
typeOK = false;
}
return typeOK;
}
private WildcardType resolveWildcardType(WildcardType type) {
Type[] lowerBounds = type.getLowerBounds();
Type[] upperBounds = type.getUpperBounds();
return new Types.WildcardTypeImpl(resolveTypes(lowerBounds), resolveTypes(upperBounds));
}
public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
while (toResolve instanceof TypeVariable) {
TypeVariable<?> typeVariable = (TypeVariable) toResolve;
toResolve = C$Gson$Types.resolveTypeVariable(context, contextRawType, typeVariable);
if (toResolve == typeVariable) {
return toResolve;
}
}
Type componentType;
Type newComponentType;
if ((toResolve instanceof Class) && ((Class) toResolve).isArray()) {
Class<?> original = (Class) toResolve;
componentType = original.getComponentType();
newComponentType = C$Gson$Types.resolve(context, contextRawType, componentType);
if (componentType != newComponentType) {
original = C$Gson$Types.arrayOf(newComponentType);
}
return original;
} else if (toResolve instanceof GenericArrayType) {
GenericArrayType original2 = (GenericArrayType) toResolve;
componentType = original2.getGenericComponentType();
newComponentType = C$Gson$Types.resolve(context, contextRawType, componentType);
if (componentType != newComponentType) {
return C$Gson$Types.arrayOf(newComponentType);
}
return original2;
} else if (toResolve instanceof ParameterizedType) {
ParameterizedType original3 = (ParameterizedType) toResolve;
Type ownerType = original3.getOwnerType();
Type newOwnerType = C$Gson$Types.resolve(context, contextRawType, ownerType);
boolean changed = newOwnerType != ownerType;
Type[] args = original3.getActualTypeArguments();
int length = args.length;
for (int t = 0; t < length; t++) {
Type resolvedTypeArgument = C$Gson$Types.resolve(context, contextRawType, args[t]);
if (resolvedTypeArgument != args[t]) {
if (!changed) {
args = (Type[]) args.clone();
changed = true;
}
args[t] = resolvedTypeArgument;
}
}
if (changed) {
return C$Gson$Types.newParameterizedTypeWithOwner(newOwnerType, original3.getRawType(), args);
}
return original3;
} else if (!(toResolve instanceof WildcardType)) {
return toResolve;
} else {
WildcardType original4 = (WildcardType) toResolve;
Type[] originalLowerBound = original4.getLowerBounds();
Type[] originalUpperBound = original4.getUpperBounds();
if (originalLowerBound.length == 1) {
Type lowerBound = C$Gson$Types.resolve(context, contextRawType, originalLowerBound[0]);
if (lowerBound != originalLowerBound[0]) {
return C$Gson$Types.supertypeOf(lowerBound);
}
return original4;
} else if (originalUpperBound.length != 1) {
return original4;
} else {
Type upperBound = C$Gson$Types.resolve(context, contextRawType, originalUpperBound[0]);
if (upperBound != originalUpperBound[0]) {
return C$Gson$Types.subtypeOf(upperBound);
}
return original4;
}
}
}
/**
* <p> Returns an array containing the sole value of {@link Object} if
* {@link WildcardType#getUpperBounds()} returns an empty array. Otherwise,
* it returns the result of <code>WildcardType.getUpperBounds()</code>
* passed into {@link #normalizeUpperBounds}. </p>
*
* @param wildcardType the subject wildcard type
* @return a non-empty array containing the upper bounds of the wildcard
* type.
*/
public static Type[] getImplicitUpperBounds(final WildcardType wildcardType) {
final Type[] bounds = wildcardType.getUpperBounds();
return bounds.length == 0 ? new Type[] { Object.class } : normalizeUpperBounds(bounds);
}