Java 11中访问子类特定方法的最优实现方案
最优实现方案:策略模式+类型分发工具类(Java 11适配)
针对外部Jar无法修改的Shape接口及其子类场景,我们可以用策略模式+类型分发工具类的组合,彻底消除重复的instanceof判断和强制类型转换,同时完美适配后续新增的Shape子类。
1. 定义处理策略的函数式接口
首先创建通用的函数式接口,封装不同Shape子类的特定方法调用逻辑:
@FunctionalInterface public interface ShapeAction<T extends Shape> { void execute(T shape); }
如果需要处理带返回值的场景,可额外定义带返回值的版本:
@FunctionalInterface public interface ShapeFunction<T extends Shape, R> { R apply(T shape); }
2. 实现类型分发工具类
创建全局的ShapeDispatcher工具类,负责注册和分发不同Shape类型的处理逻辑:
import java.util.HashMap; import java.util.Map; public class ShapeDispatcher { // 存储类型与对应处理策略的映射 private static final Map<Class<? extends Shape>, Object> HANDLERS = new HashMap<>(); // 注册无返回值的处理逻辑 public static <T extends Shape> void registerAction(Class<T> shapeClass, ShapeAction<T> action) { HANDLERS.put(shapeClass, action); } // 注册带返回值的处理逻辑 public static <T extends Shape, R> void registerFunction(Class<T> shapeClass, ShapeFunction<T, R> function) { HANDLERS.put(shapeClass, function); } // 分发无返回值的处理逻辑 @SuppressWarnings("unchecked") public static void dispatch(Shape shape) { ShapeAction<Shape> action = (ShapeAction<Shape>) HANDLERS.get(shape.getClass()); if (action != null) { action.execute(shape); } else { throw new UnsupportedOperationException("未注册该Shape类型的处理逻辑: " + shape.getClass().getName()); } } // 分发带返回值的处理逻辑 @SuppressWarnings("unchecked") public static <R> R dispatchWithResult(Shape shape) { ShapeFunction<Shape, R> function = (ShapeFunction<Shape, R>) HANDLERS.get(shape.getClass()); if (function != null) { return function.apply(shape); } throw new UnsupportedOperationException("未注册该Shape类型的带返回值处理逻辑: " + shape.getClass().getName()); } }
3. 注册子类的特定方法逻辑
在应用初始化阶段(比如启动类、配置类),注册每个Shape子类的特定方法调用逻辑:
// 注册Square的特定方法逻辑 ShapeDispatcher.registerAction(Square.class, Square::squareSpecificMethod); // 后续新增子类(比如Rectangle)时,只需新增一行注册代码即可 // ShapeDispatcher.registerAction(Rectangle.class, Rectangle::rectangleSpecificMethod); // 带返回值示例:注册Square获取边长的逻辑 ShapeDispatcher.registerFunction(Square.class, Square::getSideLength);
4. 实际调用场景
处理Shape实例时,直接调用分发方法即可,完全不需要instanceof或强转:
// 运行时类型未知的Shape实例 Shape shape = fetchShapeFromExternalService(); // 调用无返回值的特定方法 ShapeDispatcher.dispatch(shape); // 调用带返回值的特定方法 Integer squareSide = ShapeDispatcher.dispatchWithResult(shape);
方案优势
- 消除冗余代码:所有类型判断逻辑集中在Dispatcher中,避免业务代码重复写
instanceof和强转 - 开闭原则适配:新增Shape子类时,只需注册对应的处理逻辑,无需修改原有分发代码
- Java 11完全兼容:基于Lambda和泛型实现,属于Java 8+特性,在Java 11环境下无兼容性问题
- 逻辑解耦:特定方法的调用逻辑与类型判断分离,代码结构更清晰、易于维护
内容的提问来源于stack exchange,提问作者sedgy
相关产品推荐
相关产品推荐

