如何查找类实现的继承指定父接口的子接口,可使用Guava实现
实现方案
方案1:基于Guava TypeToken封装通用方法
你要的调用效果可以直接将现有逻辑封装为静态工具方法实现,和你期望的API几乎一致:
import com.google.common.reflect.TypeToken; public class TypeUtils { @SuppressWarnings("unchecked") public static <T> Class<? extends T> getInterfaceExtending(TypeToken<?> typeToken, Class<T> superInterface) { if (!superInterface.isInterface()) { throw new IllegalArgumentException("superInterface必须是接口类型"); } return (Class<? extends T>) typeToken.getTypes().interfaces() .stream() .filter(ifaceType -> ifaceType.isSubtypeOf(superInterface) && !ifaceType.getRawType().equals(superInterface)) // 存在多个子接口时自动取继承层级最深的最具体接口 .max((t1, t2) -> t1.isSubtypeOf(t2) ? 1 : -1) .map(TypeToken::getRawType) .orElse((Class<T>) superInterface); } }
调用方式完全符合你的预期:
TypeToken<? extends NetSession> sessionTT = TypeToken.of(session.getClass()); Class<? extends NetSession> sessionIface = TypeUtils.getInterfaceExtending(sessionTT, NetSession.class); // 你的测试场景下 sessionIface == HttpSession.class 成立
方案2:JDK原生反射实现(无第三方依赖)
如果不想引入Guava依赖,也可以用JDK自带的反射能力递归查找:
public class TypeUtils { @SuppressWarnings("unchecked") public static <T> Class<? extends T> getInterfaceExtending(Class<?> clazz, Class<T> superInterface) { if (!superInterface.isInterface()) { throw new IllegalArgumentException("superInterface必须是接口类型"); } Class<?>[] interfaces = clazz.getInterfaces(); Class<? extends T> result = superInterface; for (Class<?> iface : interfaces) { if (superInterface.isAssignableFrom(iface) && !iface.equals(superInterface)) { Class<? extends T> child = getInterfaceExtending(iface, superInterface); if (child.isAssignableFrom(iface)) { result = (Class<? extends T>) iface; } } } if (result.equals(superInterface) && clazz.getSuperclass() != Object.class) { return getInterfaceExtending(clazz.getSuperclass(), superInterface); } return result; } }
调用方式:
Class<? extends NetSession> sessionIface = TypeUtils.getInterfaceExtending(session.getClass(), NetSession.class);
边界说明
如果某个实现类同时实现了多个没有继承关系的NetSession子接口,上述方法默认返回层级最深的接口,你可以根据业务需求调整逻辑,比如抛出异常或者返回指定优先级的接口。
内容的提问来源于stack exchange,提问作者Николай Костин
相关产品推荐
相关产品推荐

