Java访问修饰符通过编译期强制检查防止越权访问,private实现封装而非安全防护;防业务越权需Spring Security等机制;protected和default易因模块合并或继承暴露风险;private+final+不可变返回构成完整防护链。

Java 中访问修饰符本身不“避免”越权访问,而是通过明确的边界定义,让越权行为在编译期就无法发生——不是靠运行时拦截,而是直接不让它编译通过。
别把 private 当成“防黑客”的盾牌
private 的核心作用是封装,不是安全审计。它阻止的是“语法层面的直接访问”,比如 obj.name = "xxx" 或 int x = obj.age 这类写法。一旦出现,javac 立刻报错:error: private access 或 cannot find symbol。但它不防反射、不防序列化漏洞、也不防业务逻辑层的权限绕过(比如用户A调用接口却传了用户B的ID)。
- private 字段在子类、同包类、外部类中均不可见,连字段名都“不存在”
- 它不依赖文档约定或团队自觉,是编译器强制执行的硬规则
- 真正防业务越权(如水平/垂直越权),得靠 Spring Security、自定义注解或 AOP 拦截,不是靠加个 private
别误用 protected 和 default 做“半公开”保护
很多人以为 protected 是“比 private 安全一点”,default 是“只给同事看”,结果在模块拆分或继承扩展时暴露风险。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- protected 允许跨包子类访问——意味着只要有人继承你的类,哪怕在另一个服务模块里,也能调用 protected 方法
- default(不写修饰符)看似“包内才可见”,但若多个业务模块被打进同一个 jar 包,包边界就失效了
- 除非明确设计为被继承的模板能力(如框架抽象类中的钩子方法),否则不要为字段或普通业务方法用 protected
private + final + 不可变返回,才是完整防护链
仅 private 不够:如果 getter 返回一个 ArrayList 或 Date 引用,调用方仍能修改内部状态,等于“开门放人进来,还把钥匙交给他”。
立即学习“Java免费学习笔记(深入)”;
- 基本类型字段建议加 final,防止构造后被意外重赋值
- 引用类型字段若指向可变对象(如 List、Map、Calendar),getter 必须返回副本或不可变包装:Collections.unmodifiableList(list) 或 new ArrayList(this.items)
- 敏感字段(如 password、token)的 getter 应主动脱敏或返回 null,而不是裸露原始值
封装不是加 private 就结束,而是重设访问入口
把字段设为 private 只是第一步。关键在于:所有读写必须经过你可控的方法,且这些方法要承担校验、转换、日志等职责。
- setter 里做输入检查:年龄不能负数、邮箱格式需匹配、字符串 trim 后判空
- getter 里做输出控制:ID 脱敏、密码掩码、null 值转默认值
- 不要为每个 private 字段机械生成 getter/setter——只暴露真实需要的访问,隐藏实现细节
- 已有 public 字段要重构时,先加方法再迁移调用,避免破坏外部依赖

















