第2章 · 面向对象设计的翻车点 章节摘要:面向对象的规则背起来简单,翻起车来安静无声。本章三个事故: / 契约破坏让 HashMap 和缓存集体说谎;继承被误用为代码复用工具,把一个基础类改字段引发全站崩溃;非静态内部类持有外部引用,一次"顺手"的写法让老年代以肉眼可见的速度涨满。 学习目标 默写 / 的五条契约,解释破坏自洽性后 HashMap 的查找行为 区分"is-a"与"has-a",识别继承误用并用组合改造 说清四种内部类各自的引用关系与泄漏风险 在设计评审中用"变更影响半径"评估类关系的选择 核心概念速览 面向对象的价值不在类画得多漂亮,而在变更发生时爆炸半径有多小。 子章节导航 2.
章节摘要:面向对象的规则背起来简单,翻起车来安静无声。本章三个事故:
equals/hashCode契约破坏让 HashMap 和缓存集体说谎;继承被误用为代码复用工具,把一个基础类改字段引发全站崩溃;非静态内部类持有外部引用,一次"顺手"的写法让老年代以肉眼可见的速度涨满。
equals/hashCode 的五条契约,解释破坏自洽性后 HashMap 的查找行为面向对象的价值不在类画得多漂亮,而在变更发生时爆炸半径有多小。
只重写 equals 忘了 hashCode,去重缓存命中率为零、性能缓慢劣化——最安静的 Bug 长什么样。
一个 Stack extends ArrayList 式的设计决策,如何在三年后变成"谁也不敢动"的技术债。
Handler 持有 Activity 的教科书事故,在服务端换了个马甲继续上演。
三节都在回答同一个问题:对象之间的引用与等价关系,决定了系统的隐式耦合。
关系类型 契约/引用 事故形态 ------------ ------------------ ------------------ 逻辑等价 equals/hashCode 哈希结构失灵 静默错 结构复用 extends 基类改动 全链路震颤 对象持有 inner/anonymous 外部对象无法回收
equals 语义)。顺带说一句本章的读法。三节的排布其实是递进的:等价契约是"逻辑层"的问题,错了表现为行为不对;继承滥用是"结构层"的问题,错了表现为变更困难;内部类泄漏是"运行时"的问题,错了表现为资源耗尽。同一个对象模型,在三个不同的观察面上各暴露一种脆弱性。评审一段设计时,不妨也按这三面各扫一遍:逻辑身份是否自洽、类之间的耦合是否克制、对象之间的引用链是否会把不该留住的东西留住。多数面向对象的事故,都逃不出这三个提问。