面向对象(上):类、对象、封装、构造器、this、代码块与 static
课件来源:《第3章 面向对象(上).pptx》。本文逐项覆盖课件目录,并依据 Java SE 26、JDK 25 LTS 及相关官方文档补充现代工程实践。
面向对象的核心不是“所有东西都写成类”,而是用状态、行为、边界和不变量表达领域概念。本章完整覆盖课件上半部分。
1. 学习目标
- 区分类、对象、引用、实例字段和局部变量。
- 使用封装和构造器维护对象不变量。
- 理解
this、初始化顺序、静态成员与实例成员。 - 避免贫血对象、全局静态状态和无约束 setter。
2. 知识结构
3. 逐项详解
1. 面向对象思想
对象把相关状态与行为组织在一个边界内;类描述对象结构和可执行契约。好的模型让非法状态难以表示,并让行为靠近它所依赖的数据。
工程理解: 从业务不变量和用例出发划分职责,而不是机械地为每张数据库表生成只有 getter/setter 的类。
常见误区: 把面向对象等同于“封装、继承、多态”三个术语,忽略职责、协作和不变量。
2. 类、对象与引用
new 创建对象并返回引用;多个变量可指向同一对象。引用可为 null,字段具有默认值,局部变量必须在使用前明确赋值。
工程理解: 尽量在构造阶段创建完整对象;对可能缺失的结果使用明确契约,而不是到处传播 null。
常见误区: 把引用变量本身当作对象,或以为赋值会复制整个对象。
3. 字段、方法与访问控制
private、包可见、protected、public 决定源代码访问边界。公开方法形成 API;字段通常私有,通过有意义的行为更新。
工程理解: 优先最小可见性;包按高内聚职责组织,而不是简单按 controller/service/util 技术名拆散领域。
常见误区: 把所有字段和方法都声明为 public,导致任何调用者都能破坏状态。
4. 封装与对象不变量
封装不仅是“private + getter/setter”,而是隐藏表示方式并控制状态变化。例如余额不得为负、订单状态只能按允许路径迁移,都应在对象边界内验证。
工程理解: 暴露 withdraw、changeAddress 等业务方法,并在一个地方维护校验。
常见误区: 自动为所有字段生成可写 setter,使对象在任意时刻都可能处于非法状态。
5. 构造器与重载
构造器没有返回类型,名称与类名一致,用于建立初始状态。未声明构造器时编译器才提供默认无参构造器;一旦声明任意构造器,默认构造器便不再生成。
工程理解: 参数较多或存在可选项时使用静态工厂、builder 或值对象,避免长参数列表和布尔陷阱。
常见误区: 给构造器写 void 使其变成普通方法,或依赖已经不存在的默认构造器。
6. this 的三种用途
this.field 消除字段与参数歧义,this.method() 调用当前对象行为,this(...) 在构造器首条语句委托同类其他构造器。实例方法中的 this 指当前接收者。
工程理解: 用构造器委托集中默认值与验证,避免多个构造器复制初始化逻辑。
常见误区: 在 static 上下文使用 this,或形成构造器互相调用环。
7. 局部代码块、实例初始化块与静态初始化块
普通块限制局部变量作用域;实例初始化块在每次构造对象时执行,并被插入到构造器流程;静态初始化块在类初始化时执行一次。初始化顺序还受到父类和字段声明顺序影响。
工程理解: 复杂初始化优先具名私有方法或工厂;静态初始化避免网络、文件等不稳定 I/O。
常见误区: 依赖难以看出的初始化顺序,或在静态块抛出异常导致类无法初始化。
8. static 字段、方法与嵌套类
static 成员属于类,不依赖具体实例。静态方法只能直接访问静态成员;静态嵌套类不持有外部类实例。常量常写为 public static final,但可变静态字段会成为进程级共享状态。
工程理解: 纯函数工具和无状态工厂可使用 static;可替换依赖和有生命周期资源交给对象或依赖注入容器。
常见误区: 用 static 解决所有访问问题,造成测试污染、并发竞争和隐藏依赖。
9. 对象生命周期与垃圾回收边界
对象在没有可达引用后才有资格被 GC 回收,具体时机不确定。GC 管理 Java 堆内存,不自动关闭文件、Socket 和数据库连接。
工程理解: 外部资源使用 AutoCloseable 与 try-with-resources;内存泄漏往往来自仍被集合、监听器、ThreadLocal 或缓存引用的对象。
常见误区: 把变量设为 null 当作可靠的即时回收,或依赖 finalize() 清理资源。
3.9 最小可运行示例
public final class Example {
private Example() {}
public static <T> List<T> immutableCopy(Collection<? extends T> source) {
Objects.requireNonNull(source, "source");
return List.copyOf(source);
}
}
4. 现代 Java 校准
finalize()已废弃并不适合资源释放;使用 try-with-resources、Cleaner 的受控场景或显式生命周期。- 不可变值对象可使用 record,但仍需在紧凑构造器中校验。
- 依赖注入服务应避免可变 static 单例状态。
- 访问器不是封装的充分条件;关键是对象是否控制自己的有效状态。
5. 实践任务
- 设计 Money、Order 与 OrderLine,使金额和订单状态始终合法。
- 画出父类静态字段、实例字段、初始化块和构造器的执行顺序并用日志验证。
- 重构一个只有 getter/setter 的类,把业务状态迁移收回对象方法。
6. 掌握检查
- 能解释对象、引用和赋值别名。
- 能设计保证不变量的构造器和行为方法。
- 能说明 this、static 和初始化块的执行边界。
- 能区分堆内存回收与外部资源关闭。