static Type getParameterUpperBound(int index, ParameterizedType type) { Type[] types = type.getActualTypeArguments(); if (index < 0 || index >= types.length) { throw new IllegalArgumentException( "Index " + index + " not in range [0," + types.length + ") for " + type); } Type paramType = types[index]; if (paramType instanceof WildcardType) { return ((WildcardType) paramType).getUpperBounds()[0]; } return paramType; }
private static TypeToken<?> getFirstTypeParameter(Type type) { if (type instanceof ParameterizedType) { return TypeToken.of(((ParameterizedType) type).getActualTypeArguments()[0]); } else { return TypeToken.of(Object.class); } }
/** Returns the captured type. */ final Type capture() { Type superclass = getClass().getGenericSuperclass(); checkArgument(superclass instanceof ParameterizedType, "%s isn't parameterized", superclass); return ((ParameterizedType) superclass).getActualTypeArguments()[0]; } }
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); }
@Override public boolean equals(Object other) { if (!(other instanceof ParameterizedType)) { return false; } ParameterizedType that = (ParameterizedType) other; return getRawType().equals(that.getRawType()) && Objects.equal(getOwnerType(), that.getOwnerType()) && Arrays.equals(getActualTypeArguments(), that.getActualTypeArguments()); }
static WildcardType getWildcardType(String methodName) throws Exception { ParameterizedType parameterType = (ParameterizedType) WithWildcardType.class.getDeclaredMethod(methodName, List.class) .getGenericParameterTypes()[0]; return (WildcardType) parameterType.getActualTypeArguments()[0]; } }
@Override void visitParameterizedType(ParameterizedType parameterizedType) { Class<?> rawClass = (Class<?>) parameterizedType.getRawType(); TypeVariable<?>[] vars = rawClass.getTypeParameters(); Type[] typeArgs = parameterizedType.getActualTypeArguments(); checkState(vars.length == typeArgs.length); for (int i = 0; i < vars.length; i++) { map(new TypeVariableKey(vars[i]), typeArgs[i]); } visit(rawClass); visit(parameterizedType.getOwnerType()); }
private static Type resolveTypeVariable( Type context, Class<?> contextRawType, TypeVariable<?> unknown) { Class<?> declaredByRaw = declaringClassOf(unknown); // We can't reduce this further. if (declaredByRaw == null) return unknown; Type declaredBy = getGenericSupertype(context, contextRawType, declaredByRaw); if (declaredBy instanceof ParameterizedType) { int index = indexOf(declaredByRaw.getTypeParameters(), unknown); return ((ParameterizedType) declaredBy).getActualTypeArguments()[index]; } return unknown; }
private static <T> Type aWildcardType() { ParameterizedType parameterizedType = (ParameterizedType) new TypeCapture<List<? extends T>>() {}.capture(); return parameterizedType.getActualTypeArguments()[0]; } }
Type getTargetType(String methodName) throws Exception { ParameterizedType parameterType = (ParameterizedType) WithGenericBound.class.getDeclaredMethod(methodName, List.class) .getGenericParameterTypes()[0]; parameterType = (ParameterizedType) TypeToken.of(this.getClass()).resolveType(parameterType).getType(); return parameterType.getActualTypeArguments()[0]; } }
public void testWithMutualRecursiveBoundInTypeVariable() throws Exception { ParameterizedType paramType = (ParameterizedType) new WithGenericBound<String>() {}.getTargetType("withMutualRecursiveBound"); TypeVariable<?> k = (TypeVariable<?>) paramType.getActualTypeArguments()[0]; TypeVariable<?> v = (TypeVariable<?>) paramType.getActualTypeArguments()[1]; assertEquals(Types.newParameterizedType(List.class, v), k.getBounds()[0]); assertEquals(Types.newParameterizedType(List.class, k), v.getBounds()[0]); }
public void testResolveToGenericArrayType() { GenericArrayType arrayType = (GenericArrayType) new Holder<List<int[][]>[]>() {}.getContentType(); ParameterizedType listType = (ParameterizedType) arrayType.getGenericComponentType(); assertEquals(List.class, listType.getRawType()); assertEquals(Types.newArrayType(int[].class), listType.getActualTypeArguments()[0]); }
public void testResolveType_fromWildcard() { ParameterizedType withWildcardType = (ParameterizedType) new TypeCapture<Comparable<? extends Iterable<String>>>() {}.capture(); TypeToken<?> wildcardType = TypeToken.of(withWildcardType.getActualTypeArguments()[0]); assertEquals( String.class, wildcardType.resolveType(Iterable.class.getTypeParameters()[0]).getType()); }
public void testGetSubtype_genericSubtypeOfGenericTypeWithFewerParameters() { TypeToken<List<String>> supertype = new TypeToken<List<String>>() {}; TypeToken<MySpecialList<String, ?>> subtype = new TypeToken<MySpecialList<String, ?>>() {}; assertTrue(subtype.isSubtypeOf(supertype)); ParameterizedType actualSubtype = (ParameterizedType) supertype.getSubtype(subtype.getRawType()).getType(); assertEquals(MySpecialList.class, actualSubtype.getRawType()); assertThat(actualSubtype.getActualTypeArguments()[0]).isEqualTo(String.class); assertThat(actualSubtype.getActualTypeArguments()[1]).isInstanceOf(TypeVariable.class); assertTrue(TypeToken.of(actualSubtype).isSubtypeOf(supertype)); }
public void testGetGenericSuperclass_withSuperclass() { TypeToken<? super ArrayList<String>> superToken = new TypeToken<ArrayList<String>>() {}.getGenericSuperclass(); assertEquals(ArrayList.class.getSuperclass(), superToken.getRawType()); assertEquals( String.class, ((ParameterizedType) superToken.getType()).getActualTypeArguments()[0]); assertEquals(TypeToken.of(Base.class), TypeToken.of(Sub.class).getGenericSuperclass()); assertEquals(TypeToken.of(Object.class), TypeToken.of(Sub[].class).getGenericSuperclass()); }
public void testResolveType_parameterizedType() { @SuppressWarnings("rawtypes") // trying to test raw type Parameterized<?, ?, ?> parameterized = new Parameterized<TypeTokenResolutionTest, Bar, String>() {}; TypeResolver typeResolver = TypeResolver.covariantly(parameterized.getClass()); ParameterizedType resolved = (ParameterizedType) typeResolver.resolveType(parameterized.parameterizedType()); assertEquals(TypeTokenResolutionTest.class, resolved.getOwnerType()); assertEquals(Bar.class, resolved.getRawType()); assertThat(resolved.getActualTypeArguments()).asList().contains(String.class); }
public void testWildcardCaptured_typeVariableDeclaresTypeBound_wildcardHasNoExplicitUpperBound() throws Exception { TypeToken<Counter<?>> type = new TypeToken<Counter<?>>() {}; TypeToken<?> fieldType = type.resolveType(Counter.class.getDeclaredField("counts").getGenericType()); Type[] typeArgs = ((ParameterizedType) fieldType.getType()).getActualTypeArguments(); assertThat(typeArgs).asList().hasSize(1); TypeVariable<?> captured = (TypeVariable<?>) typeArgs[0]; assertThat(captured.getBounds()).asList().containsExactly(Number.class); assertThat(new TypeToken<List<? extends Number>>() {}.isSupertypeOf(fieldType)).isTrue(); assertThat(new TypeToken<List<? extends Iterable<?>>>() {}.isSupertypeOf(fieldType)).isFalse(); }
public void testWildcardCaptured_wildcardWithImplicitBound() throws Exception { TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {}; ImmutableList<Parameter> parameters = type.method(Holder.class.getDeclaredMethod("setList", List.class)).getParameters(); assertThat(parameters).hasSize(1); TypeToken<?> parameterType = parameters.get(0).getType(); Type[] typeArgs = ((ParameterizedType) parameterType.getType()).getActualTypeArguments(); assertThat(typeArgs).asList().hasSize(1); TypeVariable<?> captured = (TypeVariable<?>) typeArgs[0]; assertThat(captured.getBounds()).asList().containsExactly(Object.class); assertThat(new TypeToken<List<?>>() {}.isSupertypeOf(parameterType)).isTrue(); }
public void testWildcardCaptured_wildcardWithExplicitBound() throws Exception { TypeToken<Holder<? extends Number>> type = new TypeToken<Holder<? extends Number>>() {}; ImmutableList<Parameter> parameters = type.method(Holder.class.getDeclaredMethod("setList", List.class)).getParameters(); assertThat(parameters).hasSize(1); TypeToken<?> parameterType = parameters.get(0).getType(); Type[] typeArgs = ((ParameterizedType) parameterType.getType()).getActualTypeArguments(); assertThat(typeArgs).asList().hasSize(1); TypeVariable<?> captured = (TypeVariable<?>) typeArgs[0]; assertThat(captured.getBounds()).asList().containsExactly(Number.class); assertThat(new TypeToken<List<? extends Number>>() {}.isSupertypeOf(parameterType)).isTrue(); }
public void testGetSubtype_genericSubtypeOfNonGenericType() { TypeToken<Serializable> supertype = new TypeToken<Serializable>() {}; TypeToken<ArrayList<String>> subtype = new TypeToken<ArrayList<String>>() {}; assertTrue(subtype.isSubtypeOf(supertype)); ParameterizedType actualSubtype = (ParameterizedType) supertype.getSubtype(subtype.getRawType()).getType(); assertEquals(ArrayList.class, actualSubtype.getRawType()); assertThat(actualSubtype.getActualTypeArguments()[0]).isInstanceOf(TypeVariable.class); assertTrue(TypeToken.of(actualSubtype).isSubtypeOf(supertype)); }