Types { public static Type collectionElementType(Type context, Class<?> contextRawType) { Type collectionType = getSupertype(context, contextRawType, Collection.class); if (collectionType instanceof WildcardType) { collectionType = ((WildcardType) collectionType).getUpperBounds()[0]; } if (collectionType instanceof ParameterizedType) { return ((ParameterizedType) collectionType).getActualTypeArguments()[0]; } return Object.class; } private  Types(); static ParameterizedType newParameterizedType(Type rawType, Type... typeArguments); static ParameterizedType newParameterizedTypeWithOwner(
            Type ownerType, Type rawType, Type... typeArguments); static GenericArrayType arrayOf(Type componentType); static WildcardType subtypeOf(Type bound); static WildcardType supertypeOf(Type bound); static Class<?> getRawType(Type type); static boolean equals(@Nullable Type a, @Nullable Type b); static Type collectionElementType(Type context, Class<?> contextRawType);  }
@Test public void collectionElementType() throws Exception { Type arrayListOfMapOfStringIntegerType = TypesTest.class.getDeclaredField( "arrayListOfMapOfStringInteger").getGenericType(); Type mapOfStringIntegerType = TypesTest.class.getDeclaredField( "mapOfStringInteger").getGenericType(); assertThat(Types.collectionElementType(arrayListOfMapOfStringIntegerType, List.class), is(equalTo(mapOfStringIntegerType))); }