@Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof ParameterizedType)) { return false; } ParameterizedType otherType = (ParameterizedType) other; return (otherType.getOwnerType() == null && this.rawType.equals(otherType.getRawType()) && Arrays.equals(this.typeArguments, otherType.getActualTypeArguments())); }
/** * Finds the generic type (parametrized type) of the field. If the field is not generic it returns Object.class. * * @param field the field to inspect */ public Class<?> getGenericType(Field field) { Type generic = field.getGenericType(); if (generic instanceof ParameterizedType) { Type actual = ((ParameterizedType) generic).getActualTypeArguments()[0]; if (actual instanceof Class) { return (Class<?>) actual; } else if (actual instanceof ParameterizedType) { //in case of nested generics we don't go deep return (Class<?>) ((ParameterizedType) actual).getRawType(); } } return Object.class; }
/** * Get parameterized type * * @param genericType generic type * @param index index of the target parameterized type * @return Return Person.class for List<Person>, return Person.class for Map<String, Person> when index=0 */ private static Type getGenericClassByIndex(Type genericType, int index) { Type clazz = null; // find parameterized type if (genericType instanceof ParameterizedType) { ParameterizedType t = (ParameterizedType) genericType; Type[] types = t.getActualTypeArguments(); clazz = types[index]; } return clazz; }
@Override public Class<?> rawType() { return (Class<?>) parameterizedType.getRawType(); } }
@Nullable private ResolvableType resolveVariable(TypeVariable<?> variable) { if (this.type instanceof TypeVariable) { return resolveType().resolveVariable(variable); } if (this.type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) this.type; Class<?> resolved = resolve(); if (resolved == null) { return null; } TypeVariable<?>[] variables = resolved.getTypeParameters(); for (int i = 0; i < variables.length; i++) { if (ObjectUtils.nullSafeEquals(variables[i].getName(), variable.getName())) { Type actualType = parameterizedType.getActualTypeArguments()[i]; return forType(actualType, this.variableResolver); } } Type ownerType = parameterizedType.getOwnerType(); if (ownerType != null) { return forType(ownerType, this.variableResolver).resolveVariable(variable); } } if (this.variableResolver != null) { return this.variableResolver.resolveVariable(variable); } return null; }
/** * Returns the owner type of a {@link ParameterizedType} or enclosing class of a {@link Class}, or * null otherwise. */ private @Nullable Type getOwnerTypeIfPresent() { if (runtimeType instanceof ParameterizedType) { return ((ParameterizedType) runtimeType).getOwnerType(); } else if (runtimeType instanceof Class<?>) { return ((Class<?>) runtimeType).getEnclosingClass(); } else { return null; } }
@Override public boolean canWrite(@Nullable Type type, @Nullable Class<?> clazz, @Nullable MediaType mediaType) { if (!(type instanceof ParameterizedType)) { return (type instanceof Class && ResourceRegion.class.isAssignableFrom((Class<?>) type)); } ParameterizedType parameterizedType = (ParameterizedType) type; if (!(parameterizedType.getRawType() instanceof Class)) { return false; } Class<?> rawType = (Class<?>) parameterizedType.getRawType(); if (!(Collection.class.isAssignableFrom(rawType))) { return false; } if (parameterizedType.getActualTypeArguments().length != 1) { return false; } Type typeArgument = parameterizedType.getActualTypeArguments()[0]; if (!(typeArgument instanceof Class)) { return false; } Class<?> typeArgumentClass = (Class<?>) typeArgument; return ResourceRegion.class.isAssignableFrom(typeArgumentClass); }
/** * Get parameterized type * * @param genericType generic type * @param index index of the target parameterized type * @return Return Person.class for List<Person>, return Person.class for Map<String, Person> when index=0 */ private static Type getGenericClassByIndex(Type genericType, int index) { Type clazz = null; // find parameterized type if (genericType instanceof ParameterizedType) { ParameterizedType t = (ParameterizedType) genericType; Type[] types = t.getActualTypeArguments(); clazz = types[index]; } return clazz; }
@Override public Class<?> rawType() { return (Class<?>) parameterizedType.getRawType(); }
private static ClassOwnership detectJvmBehavior() { class LocalClass<T> {} Class<?> subclass = new LocalClass<String>() {}.getClass(); ParameterizedType parameterizedType = (ParameterizedType) subclass.getGenericSuperclass(); for (ClassOwnership behavior : ClassOwnership.values()) { if (behavior.getOwnerType(LocalClass.class) == parameterizedType.getOwnerType()) { return behavior; } } throw new AssertionError(); } }
@Override void visitParameterizedType(ParameterizedType fromParameterizedType) { if (to instanceof WildcardType) { return; // Okay to say Foo<A> is <?> } ParameterizedType toParameterizedType = expectArgument(ParameterizedType.class, to); if (fromParameterizedType.getOwnerType() != null && toParameterizedType.getOwnerType() != null) { populateTypeMappings( mappings, fromParameterizedType.getOwnerType(), toParameterizedType.getOwnerType()); } checkArgument( fromParameterizedType.getRawType().equals(toParameterizedType.getRawType()), "Inconsistent raw type: %s vs. %s", fromParameterizedType, to); Type[] fromArgs = fromParameterizedType.getActualTypeArguments(); Type[] toArgs = toParameterizedType.getActualTypeArguments(); checkArgument( fromArgs.length == toArgs.length, "%s not compatible with %s", fromParameterizedType, toParameterizedType); for (int i = 0; i < fromArgs.length; i++) { populateTypeMappings(mappings, fromArgs[i], toArgs[i]); } }
public static Class<?> getGenericClass(Class<?> cls, int i) { try { ParameterizedType parameterizedType = ((ParameterizedType) cls.getGenericInterfaces()[0]); Object genericClass = parameterizedType.getActualTypeArguments()[i]; if (genericClass instanceof ParameterizedType) { // handle nested generic type return (Class<?>) ((ParameterizedType) genericClass).getRawType(); } else if (genericClass instanceof GenericArrayType) { // handle array generic type return (Class<?>) ((GenericArrayType) genericClass).getGenericComponentType(); } else if (((Class) genericClass).isArray()) { // Requires JDK 7 or higher, Foo<int[]> is no longer GenericArrayType return ((Class) genericClass).getComponentType(); } else { return (Class<?>) genericClass; } } catch (Throwable e) { throw new IllegalArgumentException(cls.getName() + " generic type undefined!", e); } }
public static <T> Class<T> resolveGenericType(Class<?> declaredClass) { ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); return (Class<T>) actualTypeArguments[0]; } }
/** Returns true if {@code parameterTypes[offset..]} contains only JsonAdapters. */ private static boolean parametersAreJsonAdapters(int offset, Type[] parameterTypes) { for (int i = offset, length = parameterTypes.length; i < length; i++) { if (!(parameterTypes[i] instanceof ParameterizedType)) return false; if (((ParameterizedType) parameterTypes[i]).getRawType() != JsonAdapter.class) return false; } return true; }
/** * Returns the owner type of a {@link ParameterizedType} or enclosing class of a {@link Class}, or * null otherwise. */ @NullableDecl private Type getOwnerTypeIfPresent() { if (runtimeType instanceof ParameterizedType) { return ((ParameterizedType) runtimeType).getOwnerType(); } else if (runtimeType instanceof Class<?>) { return ((Class<?>) runtimeType).getEnclosingClass(); } else { return null; } }
private static ParameterizedType canonicalizeWildcardsInParameterizedType( ParameterizedType type) { Class<?> rawType = (Class<?>) type.getRawType(); TypeVariable<?>[] typeVars = rawType.getTypeParameters(); Type[] typeArgs = type.getActualTypeArguments(); for (int i = 0; i < typeArgs.length; i++) { typeArgs[i] = canonicalizeTypeArg(typeVars[i], typeArgs[i]); } return Types.newParameterizedTypeWithOwner(type.getOwnerType(), rawType, typeArgs); }
public static Class<?> getGenericClass(Class<?> cls, int i) { try { ParameterizedType parameterizedType = ((ParameterizedType) cls.getGenericInterfaces()[0]); Object genericClass = parameterizedType.getActualTypeArguments()[i]; if (genericClass instanceof ParameterizedType) { // handle nested generic type return (Class<?>) ((ParameterizedType) genericClass).getRawType(); } else if (genericClass instanceof GenericArrayType) { // handle array generic type return (Class<?>) ((GenericArrayType) genericClass).getGenericComponentType(); } else if (((Class) genericClass).isArray()) { // Requires JDK 7 or higher, Foo<int[]> is no longer GenericArrayType return ((Class) genericClass).getComponentType(); } else { return (Class<?>) genericClass; } } catch (Throwable e) { throw new IllegalArgumentException(cls.getName() + " generic type undefined!", e); } }
public static <T> Class<T> resolveGenericType(Class<?> declaredClass) { ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); return (Class<T>) actualTypeArguments[0]; } }
public static Class<?> typeToClass(Type type) { if (type instanceof Class) { @SuppressWarnings("unchecked") Class<?> clazz = (Class<?>) type; return clazz; } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; return (Class<?>) parameterizedType.getRawType(); } return null; }
private static ClassOwnership detectJvmBehavior() { class LocalClass<T> {} Class<?> subclass = new LocalClass<String>() {}.getClass(); ParameterizedType parameterizedType = (ParameterizedType) subclass.getGenericSuperclass(); for (ClassOwnership behavior : ClassOwnership.values()) { if (behavior.getOwnerType(LocalClass.class) == parameterizedType.getOwnerType()) { return behavior; } } throw new AssertionError(); } }