封装本身不直接提供安全性,而是通过访问控制(如private)、校验逻辑、不可变设计和包级限制等手段实现安全控制。

封装本身不直接提供“安全性”,但它通过限制访问、隐藏实现细节,为安全控制打下基础。Java中真正起作用的是访问控制机制(如private、public等)与合理设计的结合。
用private封住内部状态,只暴露必要接口
类的字段应默认设为private,避免外部直接读写。比如用户年龄不能被随意修改,就得拦在构造或setter里校验:
- 把
age声明为private int age; - 提供
setAge(int age)方法,在里面判断是否在合理范围(如0–150) - 不提供
getAge()也没关系——如果业务上不需要读取,就别暴露
getter/setter不是摆设,要承担校验责任
很多人以为加了getter/setter就是封装,其实关键在“有没有逻辑”。空壳方法等于没封:
- 错误示范:
public void setName(String name) { this.name = name; }(未判空、未去前后空格) - 正确做法:检查
name != null && !name.trim().isEmpty(),再赋值 - 敏感字段(如密码)可只提供
setPassword(),不提供getPassword(),或返回null/"***"
用final和不可变对象减少意外修改
基础类型用final可防重赋值;引用类型若指向可变对象(如ArrayList),需防御性拷贝:
立即学习“Java免费学习笔记(深入)”;
-
private final String id;—— ID一旦设定就不许变 - 若字段是
List,tags getTags()不应返回原引用,而应返回new ArrayList(this.tags) - 考虑用
Collections.unmodifiableList()包装后返回,更轻量且明确表达“只读”意图
包级访问控制也是封装一环
不加访问修饰符(即默认包私有)比public更安全,适合内部协作类:
-
工具类、DTO、实体类中的辅助方法,若只在本包内使用,就别设成
public - 模块化开发中,配合
module-info.java导出(exports)特定包,进一步约束可见范围 - 测试类可放在同一包下,方便访问包私有成员做白盒测试,又不影响外部调用
基本上就这些。封装不是靠加个private就完事,而是围绕“谁该知道什么、谁能改什么”持续做判断。做得好,漏洞少一半。










