Java单例类Final变量命名规范咨询:常量式还是驼峰式?
单例类中Final变量的命名规范:终结代码评审争议
这真的是个在团队代码评审里反复“拉锯”的问题!我来分享下业内普遍认可的判断逻辑,帮你理清该用哪种命名方式:
核心原则其实很简单:区分这个final变量是「全局常量」还是「单例实例的不可变成员」
1. 用全大写下划线命名的场景
当这个final变量满足以下所有条件时,它属于「全局常量」,应该用SOME_OBJECT这种格式:
- 它是
static final修饰的(不依赖单例实例,类加载时就确定) - 值是固定不变的(不仅引用不可变,代表的业务/系统逻辑值也不会变,比如固定阈值、枚举映射、默认配置值)
- 本质是全局共享的常量,只是碰巧放在单例类里
举个例子:
public class PaymentServiceSingleton { // 全局常量:固定的支付超时时间,不依赖实例 private static final int PAYMENT_TIMEOUT_MS = 30000; // 全局常量:默认的支付失败提示语 private static final String DEFAULT_FAIL_MESSAGE = "支付失败,请稍后重试"; private final PaymentGateway gateway; // ... 其他代码 }
2. 用驼峰命名的场景
当这个final变量是单例实例的不可变成员时,应该用someObject这种驼峰格式:
- 它只是
final修饰(非static),依赖单例实例的初始化逻辑(比如通过构造函数注入的依赖) - 它是单例实例持有的专属资源/依赖,虽然引用不可变,但本质是属于这个单例实例的成员,而非全局常量
举个例子:
public class PaymentServiceSingleton { // 单例实例的不可变依赖:支付网关实例,由构造注入,属于该单例的成员 private final PaymentGateway paymentGateway; // 单例初始化时注入依赖,一旦赋值就不再改变 private PaymentServiceSingleton(PaymentGateway gateway) { this.paymentGateway = gateway; } // ... 单例获取方法和业务逻辑 }
关键误区澄清
很多人会因为单例只有一个实例,就把它的final成员当成常量——但其实final只是保证引用不可变,而常量的核心是「值固定、全局共享、不依赖实例」。单例的final成员本质还是实例级的不可变变量,只是这个实例只有一个而已。
最后建议:把这个判断逻辑写入团队的编码规范文档里,下次评审再遇到这个问题,直接拿规范说话就行啦~
内容的提问来源于stack exchange,提问作者ninja.coder
相关产品推荐
相关产品推荐

