Types { static Type[] mapKeyAndValueTypes(Type context, Class<?> contextRawType) { if (context == Properties.class) return new Type[]{String.class, String.class}; Type mapType = getSupertype(context, contextRawType, Map.class); if (mapType instanceof ParameterizedType) { ParameterizedType mapParameterizedType = (ParameterizedType) mapType; return mapParameterizedType.getActualTypeArguments(); } return new Type[]{Object.class, 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 mapKeyAndValueTypes() throws Exception { Type mapOfStringIntegerType = TypesTest.class.getDeclaredField( "mapOfStringInteger").getGenericType(); assertThat(Types.mapKeyAndValueTypes(mapOfStringIntegerType, Map.class), is(Matchers.<Type>arrayContaining(String.class, Integer.class))); }
@Test public void propertiesTypes() throws Exception { assertThat(Types.mapKeyAndValueTypes(Properties.class, Properties.class), is(Matchers.<Type>arrayContaining(String.class, String.class))); }
@Test public void fixedVariablesTypes() throws Exception { assertThat(Types.mapKeyAndValueTypes(StringIntegerMap.class, StringIntegerMap.class), is(Matchers.<Type>arrayContaining(String.class, Integer.class))); }