如何判断给定对象是否为泛型并获取其参数数量?
判断对象是否为泛型及获取泛型参数数量
首先得明确:Java的类型擦除机制确实会抹掉运行时普通泛型实例的具体泛型参数信息——比如你创建ArrayList<String>,JVM运行时只认它是ArrayList,不知道原本的泛型参数是String。但这不代表我们完全没法做相关查询,得分情况讨论:
1. 判断对象的类是否为泛型类
如果你想知道某个对象所属的类本身是不是泛型类(比如ArrayList是泛型类,String不是),这完全可以实现:
public static boolean isGenericClass(Object obj) { Class<?> clazz = obj.getClass(); // 获取类定义时的泛型参数数组,长度大于0就说明是泛型类 return clazz.getTypeParameters().length > 0; }
比如调用isGenericClass(new ArrayList<>())会返回true,调用isGenericClass("hello")则返回false。
2. 获取泛型参数的数量
这里分两种场景:
场景A:获取类定义时的泛型参数数量
和上面的判断逻辑类似,直接取TypeParameters数组的长度就行:
public static int getGenericParamCount(Object obj) { Class<?> clazz = obj.getClass(); return clazz.getTypeParameters().length; }
比如HashMap的泛型参数数量是2,ArrayList是1,调用这个方法就能得到对应数字。
场景B:获取实例化时实际使用的泛型参数数量(仅部分情况可行)
如果对象是在保留了泛型信息的上下文中创建的(比如子类继承泛型父类时明确指定了泛型参数,或者通过反射获取的带泛型的类型),我们可以通过getGenericSuperclass()或getGenericInterfaces()来获取实际参数数量。举个例子:
// 定义子类,明确指定父类的泛型参数 class StringArrayList extends ArrayList<String> {} public static void main(String[] args) { StringArrayList list = new StringArrayList(); Type genericSuperclass = list.getClass().getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) genericSuperclass; // 这里会返回1,因为实例化时指定了1个泛型参数 int actualParamCount = paramType.getActualTypeArguments().length; System.out.println(actualParamCount); } }
但如果是直接创建new ArrayList<String>(),运行时类型擦除已经把String的信息抹掉了,就没法直接获取实例化时的参数数量。
总结
- 判断类本身是否为泛型类、获取类定义时的泛型参数数量:完全可以实现,用
Class.getTypeParameters()即可。 - 获取实例化时实际使用的泛型参数数量:只有当泛型信息被保留在类的继承/实现结构中时才能做到,普通泛型实例不行,这是类型擦除的限制。
内容的提问来源于stack exchange,提问作者ayushgp
相关产品推荐
相关产品推荐

