面试题答案
一键面试遇到的问题
- 类型擦除:Java 泛型是通过类型擦除实现的,在运行时,泛型类型信息会被擦除。这意味着在反射中,无法直接获取泛型的具体类型参数,比如
List<T>
在运行时只知道是List
,不知道T
的实际类型。 - 方法签名冲突:对于不同泛型参数但方法签名在擦除后相同的方法,反射难以区分。例如
public <T> void genericMethod(List<T> list)
和public <U> void genericMethod(List<U> list)
,在运行时它们的签名相同,这可能导致反射调用方法时出现不确定性。
解决方案及代码示例
- 调用带有泛型参数的方法: 假设存在如下类:
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class GenericMethodExample {
public <T> void genericMethod(List<T> list) {
System.out.println("Generic method called with list: " + list);
}
}
通过反射调用该方法的代码如下:
public class ReflectGenericMethod {
public static void main(String[] args) throws Exception {
GenericMethodExample example = new GenericMethodExample();
Class<?> clazz = example.getClass();
// 获取方法
Method method = clazz.getMethod("genericMethod", List.class);
// 创建参数列表
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
// 调用方法
method.invoke(example, stringList);
}
}
在上述代码中:
- 首先获取
GenericMethodExample
类的Class
对象。 - 然后通过
getMethod
方法获取genericMethod
方法,由于类型擦除,这里只需要传入擦除后的参数类型List.class
。 - 创建一个
List<String>
作为参数,最后通过method.invoke
调用方法,将example
实例和stringList
作为参数传入。虽然在反射调用时无法获取泛型的具体类型参数,但可以正常调用方法并传递合适的参数列表。