private String nameFor(WildcardType wild) { if ((wild.getLowerBounds().length != 0)) { return nameFor(wild.getLowerBounds()[0]); } else { return nameFor(wild.getUpperBounds()[0]); } }
public boolean equals(Object o) { if (o instanceof WildcardType) { WildcardType wt = (WildcardType) o; return Arrays.equals(upperBounds, wt.getUpperBounds()) && Arrays.equals(lowerBounds, wt.getLowerBounds()); } else return false; }
@Nullable private static Class<?> getErasure(Type type) { if (type instanceof Class) { return (Class) type; } if (type instanceof ParameterizedType) { return getErasure(((ParameterizedType) type).getRawType()); } if (type instanceof TypeVariable) { for (final Type bound : ((TypeVariable) type).getBounds()) { final Class<?> aClass = getErasure(bound); if (aClass != null) { return aClass; } } } if (type instanceof WildcardType) { final WildcardType wildcardType = (WildcardType) type; for (final Type bound : wildcardType.getUpperBounds()) { final Class<?> aClass = getErasure(bound); if (aClass != null) { return aClass; } } } return null; }
@Nullable private static TypeWrapper wrap(Type type) { if (type == null) { return null; } else if (type instanceof Class) { return new ClassTypeWrapper((Class<?>) type); } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; return new ParameterizedTypeWrapper( toWrappers(parameterizedType.getActualTypeArguments()), (ClassTypeWrapper) wrap(parameterizedType.getRawType()), wrap(parameterizedType.getOwnerType())); } else if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType) type; return new WildcardTypeWrapper( toWrappers(wildcardType.getUpperBounds()), toWrappers(wildcardType.getLowerBounds()), type.hashCode()); } else if (type instanceof TypeVariable) { TypeVariable<?> typeVariable = (TypeVariable<?>) type; return new TypeVariableTypeWrapper( typeVariable.getName(), toWrappers(typeVariable.getBounds()), type.hashCode()); } else if (type instanceof GenericArrayType) { GenericArrayType genericArrayType = (GenericArrayType) type; return new GenericArrayTypeWrapper( wrap(genericArrayType.getGenericComponentType()), type.hashCode()); } else { throw new IllegalArgumentException("cannot wrap type of type " + type.getClass()); } }
@Override public boolean equals(Object obj) { if (!(obj instanceof WildcardType)) return false; WildcardType other = (WildcardType) obj; return Arrays.equals(lowerBounds, other.getLowerBounds()) && Arrays.equals(upperBounds, other.getUpperBounds()); }
static String toString(WildcardType wt) { final boolean isSuper = wt.getLowerBounds().length > 0; return String.format( "? %s %s", isSuper ? "super" : "extends", isSuper ? toString(wt.getLowerBounds()) : toString(wt.getLowerBounds())); }
/** 获取一个Type类型实际对应的Class */ @SuppressWarnings("rawtypes") public static Class<?> getTypeClass(Type type) { Class<?> clazz = null; if (type instanceof Class<?>) { clazz = (Class<?>) type; } else if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; clazz = (Class<?>) pt.getRawType(); } else if (type instanceof GenericArrayType) { GenericArrayType gat = (GenericArrayType) type; Class<?> typeClass = getTypeClass(gat.getGenericComponentType()); return Array.newInstance(typeClass, 0).getClass(); } else if (type instanceof TypeVariable) { TypeVariable tv = (TypeVariable) type; Type[] ts = tv.getBounds(); if (ts != null && ts.length > 0) return getTypeClass(ts[0]); } else if (type instanceof WildcardType) { WildcardType wt = (WildcardType) type; Type[] t_low = wt.getLowerBounds(); // 取其下界 if (t_low.length > 0) return getTypeClass(t_low[0]); Type[] t_up = wt.getUpperBounds(); // 没有下界?取其上界 return getTypeClass(t_up[0]); // 最起码有Object作为上界 } return clazz; }
private Type getElementType(ParameterizedType type, int index) { Type elementType = type.getActualTypeArguments()[index]; if (elementType instanceof WildcardType) { WildcardType wildcardType = (WildcardType) elementType; return wildcardType.getUpperBounds()[0]; } return elementType; }
@Override public boolean equals(Object obj) { if (obj instanceof WildcardType) { WildcardType that = (WildcardType) obj; return lowerBounds.equals(Arrays.asList(that.getLowerBounds())) && upperBounds.equals(Arrays.asList(that.getUpperBounds())); } return false; }
public boolean equals(Object var1) { if (!(var1 instanceof WildcardType)) { return false; } else { WildcardType var2 = (WildcardType) var1; return this.lowerBounds.equals(Arrays.asList(var2.getLowerBounds())) && this.upperBounds.equals(Arrays.asList(var2.getUpperBounds())); } }
/** * @param type - something like List<? super T>, List<<? extends T>, List<? extends T & * Comparable<? super T>> * @param containingType - the shallowest type in the hierarchy where type is defined. * @return the passed type if nothing to resolve or a copy of the type with the upper and lower * bounds resolved. */ private static WildcardType resolve(WildcardType type, Type containingType) { // Use a copy because we're going to modify them. final Type[] upper = type.getUpperBounds().clone(); final Type[] lower = type.getLowerBounds().clone(); boolean modified = resolve(upper, containingType); modified = modified || resolve(lower, containingType); return modified ? create(upper, lower) : type; }
/** * Converts a Type into a jdiff compatible String. The returned types from this function should * match the same Strings that jdiff is providing to us. * * @param type the type to convert. * @return the jdiff formatted string. */ private static String typeToString(Type type) { if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; StringBuffer sb = new StringBuffer(); sb.append(typeToString(pt.getRawType())); sb.append("<"); int elementNum = 0; Type[] types = pt.getActualTypeArguments(); for (Type t : types) { sb.append(typeToString(t)); if (++elementNum < types.length) { sb.append(", "); } } sb.append(">"); return sb.toString(); } else if (type instanceof TypeVariable) { return ((TypeVariable<?>) type).getName(); } else if (type instanceof Class) { return ((Class<?>) type).getCanonicalName(); } else if (type instanceof GenericArrayType) { String typeName = typeToString(((GenericArrayType) type).getGenericComponentType()); return typeName + "[]"; } else if (type instanceof WildcardType) { WildcardType wt = (WildcardType) type; Type[] lowerBounds = wt.getLowerBounds(); if (lowerBounds.length == 0) { String name = "? extends " + concatWildcardTypes(wt.getUpperBounds()); // Special case for ? if (name.equals("? extends java.lang.Object")) { return "?"; } else { return name; } } else { String name = concatWildcardTypes(wt.getUpperBounds()) + " super " + concatWildcardTypes(wt.getLowerBounds()); // Another special case for ? name = name.replace("java.lang.Object", "?"); return name; } } else { throw new RuntimeException("Got an unknown java.lang.Type"); } }
private static boolean isWildcardTypeAssignable(WildcardType supertype, Type type) { for (Type upperBound : supertype.getUpperBounds()) { if (!isAssignable(upperBound, type)) { return false; } } for (Type lowerBound : supertype.getLowerBounds()) { if (!isAssignable(type, lowerBound)) { return false; } } return true; }
/** Returns the array type of {@code componentType}. */ static Type newArrayType(Type componentType) { if (componentType instanceof WildcardType) { WildcardType wildcard = (WildcardType) componentType; Type[] lowerBounds = wildcard.getLowerBounds(); checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds."); if (lowerBounds.length == 1) { return supertypeOf(newArrayType(lowerBounds[0])); } else { Type[] upperBounds = wildcard.getUpperBounds(); checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound."); return subtypeOf(newArrayType(upperBounds[0])); } } return JavaVersion.CURRENT.newArrayType(componentType); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; return wildcard.equals(((TypeVarBoundedType) o).typeVariable); }
static Type newArrayType(Type var0) { if (var0 instanceof WildcardType) { WildcardType var1 = (WildcardType) var0; Type[] var2 = var1.getLowerBounds(); Preconditions.checkArgument( var2.length <= 1, "Wildcard cannot have more than one lower bounds."); if (var2.length == 1) { return supertypeOf(newArrayType(var2[0])); } else { Type[] var3 = var1.getUpperBounds(); Preconditions.checkArgument(var3.length == 1, "Wildcard should have only one upper bound."); return subtypeOf(newArrayType(var3[0])); } } else { return Types.JavaVersion.CURRENT.newArrayType(var0); } }
public static Type[] getImplicitLowerBounds(WildcardType paramWildcardType) { Type[] arrayOfType = paramWildcardType.getLowerBounds(); if (arrayOfType.length == 0) { arrayOfType = new Type[1]; arrayOfType[0] = null; } return arrayOfType; }
/** * Resolves all type variables in {@code type} and all downstream types and returns a * corresponding type with type variables resolved. */ public Type resolveType(Type type) { checkNotNull(type); if (type instanceof TypeVariable) { return typeTable.resolve((TypeVariable<?>) type); } else if (type instanceof ParameterizedType) { return resolveParameterizedType((ParameterizedType) type); } else if (type instanceof GenericArrayType) { return resolveGenericArrayType((GenericArrayType) type); } else if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType) type; return new Types.WildcardTypeImpl( resolveTypes(wildcardType.getLowerBounds()), resolveTypes(wildcardType.getUpperBounds())); } else { // if Class<?>, no resolution needed, we are done. return type; } }
/** * Returns raw class for given <code>type</code> when implementation class is known and it makes * difference. * * @see #resolveVariable(java.lang.reflect.TypeVariable, Class) */ public static Class<?> getRawType(Type type, Class implClass) { if (type instanceof Class) { return (Class) type; } if (type instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) type; return getRawType(pType.getRawType(), implClass); } if (type instanceof WildcardType) { 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; } if (type instanceof GenericArrayType) { Type genericComponentType = ((GenericArrayType) type).getGenericComponentType(); Class<?> rawType = getRawType(genericComponentType, implClass); // this is sort of stupid, but there seems no other way (consider don't creating new instances // each time)... return Array.newInstance(rawType, 0).getClass(); } if (type instanceof TypeVariable) { TypeVariable<?> varType = (TypeVariable<?>) type; if (implClass != null) { Type resolvedType = resolveVariable(varType, implClass); if (resolvedType != null) { return getRawType(resolvedType, null); } } Type[] boundsTypes = varType.getBounds(); if (boundsTypes.length == 0) { return Object.class; } return getRawType(boundsTypes[0], implClass); } return null; }
private Class<?> extractInjectionClass(ParameterizedType parameterizedType) { Type type = parameterizedType.getActualTypeArguments()[0]; if (type instanceof Class) { return (Class<?>) type; } else if (type instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) type).getRawType(); } else if (type instanceof WildcardType) { // To handle for instance Class<? extends Habba>, which will then return habba WildcardType wcType = (WildcardType) type; return (Class) wcType.getUpperBounds()[0]; } else if (type instanceof TypeVariable) { TypeVariable tv = (TypeVariable) type; return (Class) tv.getBounds()[0]; } throw new IllegalArgumentException( "Could not extract injectionClass of Type " + parameterizedType); }
/** * Creates {@link TypeInformation} for the given {@link Type}. * * @param fieldType the field type * @return the type information */ @SuppressWarnings({"rawtypes", "unchecked"}) protected TypeInformation<?> createInfo(Type fieldType) { if (fieldType.equals(this.type)) { return this; } if (fieldType instanceof Class) { return new ClassTypeInformation((Class<?>) fieldType); } Map<TypeVariable, Type> variableMap = GenericTypeResolver.getTypeVariableMap(resolveType(fieldType)); if (fieldType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) fieldType; return new ParameterizedTypeInformation(parameterizedType, this); } if (fieldType instanceof TypeVariable) { TypeVariable<?> variable = (TypeVariable<?>) fieldType; return new TypeVariableTypeInformation(variable, type, this, variableMap); } if (fieldType instanceof GenericArrayType) { return new GenericArrayTypeInformation((GenericArrayType) fieldType, this); } if (fieldType instanceof WildcardType) { WildcardType wildcardType = (WildcardType) fieldType; Type[] bounds = wildcardType.getLowerBounds(); if (bounds.length > 0) { return createInfo(bounds[0]); } bounds = wildcardType.getUpperBounds(); if (bounds.length > 0) { return createInfo(bounds[0]); } } throw new IllegalArgumentException(); }
private static boolean isClassAssignableToWildcardType(Class<?> supertype, WildcardType type) { for (Type upperBound : type.getUpperBounds()) { if (!isAssignable(supertype, upperBound)) { return false; } } return true; }
private ClassNode configureWildcardType(WildcardType wildcardType) { ClassNode base = ClassHelper.makeWithoutCaching("?"); base.setRedirect(ClassHelper.OBJECT_TYPE); // TODO: more than one lower bound for wildcards? ClassNode[] lowers = configureTypes(wildcardType.getLowerBounds()); ClassNode lower = null; // TODO: is it safe to remove this? What was the original intention? if (lower != null) lower = lowers[0]; ClassNode[] upper = configureTypes(wildcardType.getUpperBounds()); GenericsType t = new GenericsType(base, upper, lower); t.setWildcard(true); ClassNode ref = ClassHelper.makeWithoutCaching(Object.class, false); ref.setGenericsTypes(new GenericsType[] {t}); return ref; }
public static Class<?> getRawClass(final Type type) { if (Class.class.isInstance(type)) { return Class.class.cast(type); } if (ParameterizedType.class.isInstance(type)) { final ParameterizedType parameterizedType = ParameterizedType.class.cast(type); return getRawClass(parameterizedType.getRawType()); } if (WildcardType.class.isInstance(type)) { final WildcardType wildcardType = WildcardType.class.cast(type); final Type[] types = wildcardType.getUpperBounds(); return getRawClass(types[0]); } if (GenericArrayType.class.isInstance(type)) { final GenericArrayType genericArrayType = GenericArrayType.class.cast(type); final Class<?> rawClass = getRawClass(genericArrayType.getGenericComponentType()); return Array.newInstance(rawClass, 0).getClass(); } return null; }
public static Class<?> getActualType(Type genericType, final int pos) { if (genericType == null) return null; if (!ParameterizedType.class.isAssignableFrom(genericType.getClass())) { if (genericType instanceof TypeVariable) genericType = getType(((TypeVariable<?>) genericType).getBounds(), pos); else if (genericType instanceof WildcardType) { final WildcardType wildcardType = (WildcardType) genericType; Type[] bounds = wildcardType.getLowerBounds(); if (bounds.length == 0) bounds = wildcardType.getUpperBounds(); genericType = getType(bounds, pos); } final Class<?> cls = (Class<?>) genericType; return cls.isArray() ? cls.getComponentType() : cls; } final ParameterizedType paramType = (ParameterizedType) genericType; final Type t = getType(paramType.getActualTypeArguments(), pos); return t instanceof Class ? (Class<?>) t : getActualType(t, pos); }
protected JavaType _fromWildcard(WildcardType type, TypeBindings context) { /* Similar to challenges with TypeVariable, we may have * multiple upper bounds. But it is also possible that if * upper bound defaults to Object, we might want to consider * lower bounds instead. * * For now, we won't try anything more advanced; above is * just for future reference. */ return _fromType(type.getUpperBounds()[0], context); }
private static void testReturnTypeIdentityref( final Class<?> clazz, final String methodName, final String returnTypeStr) throws Exception { Method method; java.lang.reflect.Type returnType; try { method = clazz.getMethod(methodName); assertEquals(java.lang.Class.class, method.getReturnType()); returnType = method.getGenericReturnType(); assertTrue(returnType instanceof ParameterizedType); final ParameterizedType pt = (ParameterizedType) returnType; final java.lang.reflect.Type[] parameters = pt.getActualTypeArguments(); assertEquals(1, parameters.length); final java.lang.reflect.Type parameter = parameters[0]; assertTrue(parameter instanceof WildcardType); final WildcardType wildcardType = (WildcardType) parameter; assertEquals("? extends " + returnTypeStr, wildcardType.toString()); } catch (final NoSuchMethodException e) { throw new AssertionError("Method '" + methodName + "' not found"); } }
/** * Returns a type that is functionally equal but not necessarily equal according to {@link * Object#equals(Object) Object.equals()}. The returned type is {@link Serializable}. */ 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) { 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 WildcardType) { WildcardType w = (WildcardType) type; return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds()); } else { // type is either serializable as-is or unsupported return type; } }
private static void testReturnTypeInstanceIdentitifer( final ClassLoader loader, final Class<?> clazz, final String methodName) throws Exception { Method method; Class<?> rawReturnType; java.lang.reflect.Type returnType; try { method = clazz.getMethod(methodName); rawReturnType = Class.forName("org.opendaylight.yangtools.yang.binding.InstanceIdentifier", true, loader); assertEquals(rawReturnType, method.getReturnType()); returnType = method.getGenericReturnType(); assertTrue(returnType instanceof ParameterizedType); final ParameterizedType pt = (ParameterizedType) returnType; final java.lang.reflect.Type[] parameters = pt.getActualTypeArguments(); assertEquals(1, parameters.length); final java.lang.reflect.Type parameter = parameters[0]; assertTrue(parameter instanceof WildcardType); final WildcardType wildcardType = (WildcardType) parameter; assertEquals("?", wildcardType.toString()); } catch (final NoSuchMethodException e) { throw new AssertionError("Method '" + methodName + "' not found"); } }
/** 得到实际Type类型对应的Class */ public static Class<?> asClass(Type actualType) { if (actualType instanceof Class) return (Class<?>) actualType; if (actualType instanceof ParameterizedType) { final Type rawType = ((ParameterizedType) actualType).getRawType(); // The sun implementation returns getRawType as Class<?>, but there is room in the interface // for it to be // some other Type. We'll assume it's a Class. // TODO: consider logging or throwing our own exception for that day when "something else" // causes some confusion return (Class) rawType; } if (actualType instanceof GenericArrayType) { final Type type = ((GenericArrayType) actualType).getGenericComponentType(); return Array.newInstance(asClass(type), 0).getClass(); } if (actualType instanceof TypeVariable) { // Support for List<T extends Number> // There is always at least one bound. If no bound is specified in the source then it will be // Object.class return asClass(((TypeVariable) actualType).getBounds()[0]); } if (actualType instanceof WildcardType) { final WildcardType wildcardType = (WildcardType) actualType; final Type[] bounds = wildcardType.getLowerBounds(); if (bounds != null && bounds.length > 0) { return asClass(bounds[0]); } // If there is no lower bounds then the only thing that makes sense is Object. return Object.class; } throw new RuntimeException(String.format("Unable to convert %s to Class.", actualType)); }