面试题答案
一键面试实现思路
- 定义泛型和工具类:定义一个泛型类型参数
T
,用于表示不同类型的对象。创建一个工具类,包含一个静态方法用于通过反射调用getData
方法。 - 获取方法并调用:使用反射获取对象的
getData
方法,然后调用该方法获取返回值。 - 处理返回值:根据泛型类型
T
来处理返回值。
核心代码
import java.lang.reflect.Method;
public class GenericReflectionUtil {
@SuppressWarnings("unchecked")
public static <T> T callGetData(Object obj) {
try {
Method method = obj.getClass().getMethod("getData");
return (T) method.invoke(obj);
} catch (Exception e) {
throw new RuntimeException("调用 getData 方法失败", e);
}
}
}
class BaseClass {
public BaseClass getData() {
return this;
}
}
class SubClass1 extends BaseClass {
@Override
public SubClass1 getData() {
return this;
}
}
class SubClass2 extends SubClass1 {
@Override
public SubClass2 getData() {
return this;
}
}
可以通过以下方式调用:
public class Main {
public static void main(String[] args) {
SubClass2 subClass2 = new SubClass2();
SubClass2 result = GenericReflectionUtil.callGetData(subClass2);
System.out.println(result);
}
}
应用场景
- 框架开发:在一些通用的框架中,可能需要处理多种不同类型但具有相似方法结构的对象。通过这种方式可以实现通用的方法调用,提高框架的灵活性和复用性。
- 插件系统:当插件可能返回不同类型但都有类似
getData
方法的对象时,使用该工具类可以方便地统一处理这些返回值。
潜在风险
- 性能问题:反射调用方法比直接调用方法慢很多,在性能敏感的场景下可能不适用。
- 类型安全问题:虽然使用了泛型,但如果反射调用的方法不存在或者返回值类型与泛型不匹配,可能会抛出运行时异常,导致程序崩溃。
- 维护成本:使用反射和泛型会增加代码的复杂性,使得代码的可读性和维护性变差,尤其是当继承体系复杂时。