前言
Java 修饰符分为两大体系:访问权限修饰符(控制类 / 成员可见范围)、非访问修饰符(定义特性、生命周期、Spring 框架专属语义)。 SpringBoot/Spring 开发中,修饰符贯穿 Controller、Service、Mapper、实体类、工具类、配置类全场景,不同修饰符搭配注解会产生截然不同的 Bean 生命周期、依赖注入、序列化、继承效果。 本文以多表格拆分 + 场景适配 + Spring 工程实操规范完整梳理。
一、第一大类:访问权限修饰符(4 个,控制可见范围)
核心作用:限定类、成员变量、成员方法、构造器可被调用的范围,作用域从小到大排序:private < 默认(包私有) < protected < public
表 1:四大访问修饰符作用域对照表
修饰符 | 中文名称 | 本类内部 | 同一个包下其他类 | 子类(不同包) | 任意包所有类 | Spring 项目常规使用场景 |
private | 私有 | ✅ 可见 | ❌ 不可见 | ❌ 不可见 | ❌ 不可见 | 1.Service 注入的 Mapper 成员变量 2. 实体类 PO/DO 所有属性字段 3. 工具类内部私有工具方法 4. 常量私有成员 |
(无修饰符) default | 包私有 / 默认 | ✅ 可见 | ✅ 可见 | ❌ 不可见 | ❌ 不可见 | Spring 极少主动使用;仅同一包内协作工具类临时方法 |
protected | 受保护 | ✅ 可见 | ✅ 可见 | ✅ 可见 | ❌ 不可见 | 1. 父类公共基础 PO 审计字段(createTime/updateTime) 2. 抽象父 Service 通用业务模板方法 |
public | 公共 | ✅ 可见 | ✅ 可见 | ✅ 可见 | ✅ 可见 | 1.Controller 所有接口方法 2.Service 接口定义、实现类对外业务方法 3.Mapper 接口 4. 对外暴露的工具类静态方法 |
表 2:访问修饰符使用硬性规范(Spring 工程最佳实践)
代码元素 | 推荐修饰符 | 禁止使用 | 原因说明 |
实体类 PO/DTO/Form 属性字段 | private | public | 封装特性,通过 get/set 访问;Jackson 序列化默认适配私有字段 |
Service 层注入 Mapper 对象 | private | public/protected | 依赖注入无需对外暴露,保证封装 |
Controller 接口请求方法 | public | 其他 | SpringMVC 需要外部反射调用接口方法,必须 public |
业务接口(XXXService) | public | default | 跨包调用实现类,必须公共 |
工具类内部工具方法 | private | public | 仅类内调用,无需对外开放 |
抽象父类模板方法 | protected | private | 供子类重写拓展,外部不可调用 |
二、第二大类:基础非访问修饰符(Java 原生核心修饰符,Spring 高频搭配注解使用)
模块 1:static 静态修饰符
表 3:static 修饰不同元素效果 + Spring 场景
修饰对象 | 核心特性 | Spring 开发适用场景 | 禁忌场景 |
static 变量(静态变量) | 属于类本身,不属于实例;全局唯一一份内存,所有对象共享 | 1. 全局常量(public static final) 2. 工具类全局配置参数 | 不能修饰 @Autowired 注入成员(静态变量无法被 Spring 自动注入) |
static 方法(静态方法) | 无需 new 实例,类名。方法名 () 直接调用;内部只能访问静态资源 | 通用工具类:日期转换、Bean 拷贝、加解密工具方法 | 不能调用非静态成员;不能加 @Transactional 事务注解(事务依赖实例代理) |
static 代码块 | 类加载时执行一次,仅初始化静态资源 | 工具类加载初始化配置、加载证书文件 | 业务层几乎不用 |
static 内部类 | 脱离外部类可独立实例化 | 复杂 DTO 嵌套内部枚举 / 子对象 | 极少使用 |
模块 2:final 最终修饰符(不可修改)
表 4:final 修饰不同元素规则对照表
修饰对象 | 语义约束 | Spring 项目使用场景 |
final 变量 | 赋值一次后永久不可修改 | 1. 全局常量: |
final 方法 | 子类无法重写该方法 | 父类固定模板方法,不允许子类篡改核心逻辑 |
final 类 | 类不能被继承(无子类) | 1. 通用工具类(BeanUtil、DateUtil) 2. 枚举类默认都是 final |
模块 3:abstract 抽象修饰符(面向接口编程核心,Spring 架构基石)
表 5:abstract 使用规则 & 业务场景
修饰对象 | 约束规则 | Spring 架构场景 |
abstract 抽象类 | 不能 new 实例;可包含抽象方法 + 普通成员变量 / 普通方法 | 通用父 BaseService、BaseController,封装分页、异常统一处理 |
abstract 抽象方法 | 无方法体,必须被子类实现重写 | 模板方法模式,定义业务标准流程,子类差异化实现 |
关键:接口 interface 默认所有方法都是 public abstract
模块 4:synchronized /volatile/transient 并发序列化修饰符
表 6:并发 & 序列化修饰符场景明细
修饰符 | 核心作用 | Spring 使用场景 |
synchronized | 同步锁,保证多线程原子性、可见性 | 定时任务多线程并发争抢资源、库存扣减简易加锁(分布式推荐 Redisson) |
volatile | 保证变量内存可见性,禁止指令重排 | 多线程全局开关标记(定时任务启停标记) |
transient | 序列化忽略字段 | PO 实体中不需要存入 Redis / 序列化的临时字段 |
三、第三大类:Spring 生态专属语义修饰(结合注解生效,Java 原生修饰符 + Spring 注解联动)
Spring 不会新增语法修饰符,但通过原生修饰符 + 框架注解赋予特殊生命周期、依赖注入、代理特性,是业务开发最常用组合。
表 7:@Autowired 注入场景修饰符搭配规范
成员变量修饰符 | 搭配 @Autowired 效果 | 推荐度 |
private | Spring 反射无视私有权限,可正常注入;封装性最好 | ⭐⭐⭐⭐⭐ 标准写法 |
protected | 子类可直接访问注入对象,适合父子 Service 继承场景 | ⭐⭐⭐⭐ |
public | 外部可随意修改注入 Bean,破坏容器单例,不推荐 | ⭐ |
final | 搭配构造注入推荐写法: | ⭐⭐⭐⭐⭐ Spring 官方推荐 |
表 8:Bean 作用域 + 修饰符联动(单例 / 多例)
修饰符组合 | Bean 生命周期特性 | 使用场景 |
private static + @Autowired | 禁止使用!静态变量只会注入一次,单例容器下会出现注入失效 | ❌ 严禁 |
private final + 构造注入 | Bean 创建完成后无法被修改,线程安全,无循环依赖隐患 | ✅ 生产首选 |
四、第四大类:方法专属修饰符汇总(接口 / 实现类方法全覆盖)
表 9:方法所有修饰符组合含义对照表
修饰符组合 | 适用位置 | 核心作用 |
public void | Controller 接口方法 | 接收前端 http 请求,SpringMVC 反射调用 |
public + @Override | Service 实现类重写接口方法 | 实现业务规范,编译器校验方法签名 |
protected abstract | 抽象父类模板方法 | 预留拓展点,子类必须实现 |
private static | 工具类内部静态工具方法 | 全局调用,无状态线程安全 |
public static final | 常量工具方法 | 逻辑永久固定,不可重写 |
private synchronized | 类内多线程同步方法 | 本地锁保证线程安全 |
五、综合总表:Spring 分层代码全层级修饰符标准配置
表 10:项目各层代码统一修饰符规范(企业级开发标准)
代码分层 | 代码元素 | 标准修饰符 | 补充说明 |
控制层 Controller | 类 | public | 交给 SpringMVC 扫描注册 Bean |
请求接口方法 | public | 必须公共才能被外部访问 | |
业务层 Service | 业务接口 | public | 跨包调用 |
接口实现类(@Service) | public | IOC 容器托管 | |
注入 Mapper 成员变量 | private final | 构造器注入官方最优方案 | |
业务实现方法 | public | 供上层调用 | |
数据访问层 Mapper | Mapper 接口 | public | MyBatis 扫描生成代理对象 |
实体层 PO/DTO/Form | 实体类 | public | 序列化反射需要 |
所有属性字段 | private | 封装,get/set 访问 | |
get/set 方法 | public | Jackson 序列化依赖公共 getter | |
通用工具类 | 工具类 | public final | 禁止继承 |
工具方法 | public static | 类名直接调用 | |
全局常量 | public static final | 统一配置常量 | |
配置类 Configuration | 配置类 | public | Spring 扫描配置 Bean |
@Bean 生成对象方法 | public | 容器注册第三方组件 |
六、高频易错坑点总结
❌ 静态变量不能使用 @Autowired:static 属于类加载阶段,早于 Spring 容器初始化,注入一定会失效;
❌ private 方法不能加 @Transactional:Spring 事务基于 JDK/CGLIB 动态代理,私有方法无法被代理拦截,事务不生效;
✅ final 成员变量推荐构造器注入:杜绝字段注入循环依赖问题,线程安全性更高;
✅ 实体属性一律 private:遵循 Java 封装原则,适配 JSON 序列化、MyBatis 字段映射;
❌ 接口内变量默认 public static final,方法默认 public abstract,无需手动书写。