Java安全业务实体类的核心是通过final+私有字段、专用类型(BigDecimal/Instant/枚举)、构造即完整校验、敏感类加final等手段,在编译期或运行初期阻断非法修改。

Java 中设计安全的业务实体类,核心不是“堵住所有修改入口”,而是让非法修改在编译期、运行初期或逻辑层面就无法成立——靠类型约束、状态封装和不可变性,把篡改成本抬高到不可行。
用 final + 私有字段锁死内部状态
所有业务关键字段声明为 private final,构造时一次性赋值,后续彻底禁止变更。比如订单金额、用户ID、创建时间等一旦生成就不该再变:
- 避免用 public 或 protected 字段,连反射都难以直接写入(配合安全管理器可进一步限制)
- 不提供 setter 方法;若需更新,应走明确的业务方法(如
applyRefund(BigDecimal refundAmount)),并在方法内校验前置条件 - 对集合类字段(如
private final List),构造时用- items
Collections.unmodifiableList()包装,防止外部 add/remove
字段类型必须承载真实业务语义
基本类型是安全漏洞温床,包装类型和专用类型才是防篡改的第一道防线:
- 金额用 BigDecimal(非 double/float),杜绝浮点误差导致的隐式篡改
- 状态用 枚举(如
OrderStatus.PAID),而非 String 或 int,避免传入 "paid1" 或 999 这类非法值 - 时间用 Instant(非 Date 或 long),明确表达不可变、时区无关的时间点
- 布尔标识用 Boolean(非 boolean),保留 null 表达“未设置”或“数据库未知”,避免误判为 false
构造即完整,拒绝半成品对象
一个实体类实例化后,必须处于合法、可用、自洽的状态:
- 全参构造器或 Builder 模式强制传入所有必填字段,不提供漏字段的构造器
- 构造函数内完成全部校验:金额 ≥ 0、手机号格式合规、状态迁移路径合法(如不能从 CANCELLED 直接变为 SHIPPED)
- 无参构造器仅用于框架反序列化(如 MyBatis、Jackson),但应加
@Deprecated注释并配合private修饰,业务代码不得调用
敏感类加 final,从继承层切断篡改路径
对不可变值对象(如 OrderId、Money)、安全校验器(如 SignatureVerifier)等,必须声明为 public final class:
- 编译期直接报错:
Cannot inherit from final 'OrderId',连字节码都不会生成 - 子类无法重写
equals、hashCode或添加可变字段,破坏一致性 - 配合 private 构造器 + 静态工厂方法(如
OrderId.of("ORD-2026-XXXX")),彻底封死非法实例化
不复杂但容易忽略:安全不是加一堆校验注解或拦截器,而是从字段定义、构造逻辑、类型选择开始,就让错误用法在 IDE 里标红、在编译时报错、在运行前被拦下。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











