和上帝一样聪明,和天才一样幼稚。——巴尔扎克《奥诺丽纳》
工具类:
public static Type[] getGenericTypes(Type paramType) { Type type; for (type = paramType; type instanceof Class; type = ((Class<?>) type).getGenericSuperclass()) { if (Object.class.equals(type)) { Type[] genericInterfaces = ((Class<?>) type).getGenericInterfaces(); if (genericInterfaces.length > 0 && Objects.nonNull(genericInterfaces[0])) { type = genericInterfaces[0]; } } } if (type instanceof ParameterizedType) { ParameterizedType ty = (ParameterizedType) type; return ty.getActualTypeArguments(); } return new Type[0]; }
public static Type[] getGenericTypes(Type paramType) { Type type; for (type = paramType; type instanceof Class; type = ((Class<?>) type).getGenericSuperclass()) { if (Object.class.equals(type)) { Type[] genericInterfaces = ((Class<?>) type).getGenericInterfaces(); if (genericInterfaces.length > 0 && Objects.nonNull(genericInterfaces[0])) { type = genericInterfaces[0]; } } } if (type instanceof ParameterizedType) { ParameterizedType ty = (ParameterizedType) type; return ty.getActualTypeArguments(); } return new Type[0]; }
使用方式:
@Test void testGetGenericTypes() { class StringArrayList extends ArrayList<String> { private static final long serialVersionUID = 5735314375293577082L; } Type[] stringType = ReflectHelper.getGenericTypes(new TypeReference<String>() {}.getClass()); Assertions.assertEquals(String.class, stringType[0]); Type[] stringArrayListType = ReflectHelper.getGenericTypes(StringArrayList.class); Assertions.assertEquals(String.class, stringArrayListType[0]); Type[] hashMapType = ReflectHelper.getGenericTypes(new HashMap<String, Object>() {}.getClass()); Assertions.assertEquals(String.class, hashMapType[0]); Assertions.assertEquals(Object.class, hashMapType[1]); }
TypeReference
:
package io.github.vampireachao.stream.core.reflect; import java.lang.reflect.Type; /** * 单个泛型类型 * * @author VampireAchao * @since 2022/6/2 18:53 */ public abstract class TypeReference<T> implements Type { /** * Returns a string describing this type, including information * about any type parameters. * * @return a string describing this type * @implSpec The default implementation calls {@code toString}. * @since 1.8 */ @Override public String getTypeName() { return ReflectHelper.getGenericTypes(this.getClass())[0].getTypeName(); } public Type getType() { return ReflectHelper.getGenericTypes(this.getClass())[0]; } }