应严格控制访问权限:字段必须private并配校验setter,方法按协作需求设权限,构造函数受控,返回不可变副本或使用不可变设计。

避免滥用 public 修饰符,核心是守住“谁需要访问”和“谁负责维护”的边界——不是所有能被访问的,都该被公开;而是只把真正需要对外协作的部分暴露出去,其余一律收紧。
字段必须用 private 封装
类的属性(字段)几乎从不应该是 public。一旦设为 public,外部代码就能绕过任何校验、日志或状态同步逻辑直接读写,等于放弃控制权。
- 反例:
public String name;→ 外部可赋值user.name = null;或空字符串,业务规则彻底失效 - 正解:声明为
private String name;,搭配getName()和setName(String),在 setter 中做非空判断、去首尾空格、触发变更通知等 - 敏感字段(如密码、余额)还应在 getter 中返回副本(如
return new BigDecimal(this.balance);),防外部篡改原始引用
方法按需开放,不为“方便”降级权限
一个方法是否设为 public,取决于它是否构成该类对外承诺的稳定契约,而不是“以后可能用到”或“写测试方便”。
- 工具型逻辑(如字符串格式化、数值校验)若只被本类调用,就用
private - 同包内多个类协作时才考虑默认(包级)权限,比如 DAO 层的通用查询模板方法
-
protected仅用于明确设计为被继承扩展的场景,例如父类留出protected void initConfig()让子类定制,而非为了“子类能直接改字段”
构造函数也要受控
构造函数加 public 意味着任何人都能随意创建实例,可能破坏单例、资源池或状态一致性。
- 需要全局唯一对象?用
private构造 + 静态工厂方法(如getInstance()) - 希望限制创建方式?比如只允许通过 Builder 构建,就把构造函数设为
private或protected - 框架集成(如 Spring)常依赖反射调用无参构造,此时可保留
public,但需配合其他手段(如 final 字段 + 不可变设计)保安全
用不可变性补强封装效果
即使字段已 private,如果 getter 返回的是内部集合或可变对象引用,外部仍可能间接破坏状态。
- 返回集合时,用
Collections.unmodifiableList(this.items)或新建副本 - 布尔字段优先用
isActive()而非getActive(),语义更清晰 - 对关键业务对象(如
User、Order),考虑设计为不可变类:所有字段final + private,构造即初始化,不提供 setter
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











