多态的核心价值是让同一段代码根据对象实际类型自动执行不同逻辑,避免用 instanceof 手动分发;应优先通过抽象方法、类型分发容器、访问者模式或 sealed 类+switch 实现,兼顾可维护性与扩展性。

多态的核心价值,是让同一段代码能根据对象实际类型自动执行不同逻辑,而不是靠一堆 instanceof 判断来“手动分发”。滥用 instanceof 本质是把本该由 JVM 和设计承担的职责,硬塞进业务代码里——既脆弱又难维护。
用多态替代分支判断
当多个子类需要对同一行为做差异化处理时,不要写 if (obj instanceof A)、else if (obj instanceof B),而应在父类或接口中定义抽象方法,由各子类自行实现。
- 例如格式化逻辑:在基类
Thing中声明String format(),让Thing1和Thing2各自提供实现,调用方只需thing.format() - 避免循环依赖:若
Thing1Formatter需调用Thing2Formatter,反过来也一样,可提取公共接口(如Formatter<t></t>)并用组合代替强引用 - 注意:这要求你能修改子类代码;若子类来自 JDK 或第三方库(如
Integer、BigDecimal),则需转向其他策略
用类型分发容器替代硬编码判断
对无法修改的类,可用 Map<class>, Function<object>></object></class> 统一注册处理逻辑,比 if-else 更易扩展和测试。
- 初始化时注册:
handlers.put(Integer.class, obj -> handleInteger((Integer)obj)) - 运行时查表:
Function<object> handler = handlers.get(obj.getClass());</object>,再安全调用 - 支持 fallback:对未注册类型,可设默认处理器或抛明确异常,而非静默忽略
- 避免在循环内反复调用
obj.getClass(),应提前缓存结果
用访问者模式解耦双类型逻辑
当操作本身与数据结构深度耦合(比如遍历复合对象树并按节点类型做不同渲染),访问者模式能把“谁来处理”和“怎么处理”分离。
立即学习“Java免费学习笔记(深入)”;
- 定义
accept(Visitor v)在每个元素类中,把 dispatch 权交给访问者 - 访问者接口按类型声明
visit(Thing1 t)、visit(Thing2 t),实现类集中编写业务逻辑 - 新增元素类型时,只需改元素类的
accept方法;新增操作时,新增访问者实现即可 - Java 14+ 的
sealed类配合switch表达式,也能实现类似效果,语法更简洁
警惕 null 和继承链陷阱
instanceof 看似简单,但误用常源于对类型系统理解偏差。
-
null instanceof X永远返回false,无需额外判空——但若逻辑依赖非 null,仍需前置校验 - 子类实例
instanceof父类为true,但父类实例instanceof子类为false;判断顺序应从具体到宽泛(先SubA再Parent),否则可能被宽泛类型提前截断 - 接口实现关系同样适用:
new ArrayList() instanceof List为true,但不能反推


















