final变量在java中不可重新赋值,天然适合定义不可变常量配置;修饰基本类型时值锁定且编译期检查,修饰引用类型时仅锁定引用而非对象内容,配合static可实现类级常量,外部配置需通过静态初始化块加载并封装访问。

final 变量在 Java 中不能被重新赋值,因此它天然适合定义不可变的常量配置,但不支持运行时修改 —— 这不是“限制失败”,而是设计初衷。
final 修饰基本类型变量:真正意义上的常量
用 final 声明基本类型(如 int、String、boolean)时,变量一旦初始化就锁定值,编译器会强制检查,任何后续赋值都会报错。
- 推荐在声明时直接初始化,例如:
public static final int MAX_RETRY = 3; - 也可在构造方法或实例初始化块中赋值(仅限非 static final),但每个对象只能赋一次
- 注意:String 是不可变类,final String 表示引用不可变,内容本身也因 String 特性无法修改
final 修饰引用类型变量:只锁引用,不锁对象内容
final 作用于数组、List、自定义对象等引用类型时,仅禁止该变量指向另一个对象,但对象内部状态仍可修改。
- 例如:
final List<string> configList = new ArrayList();</string>合法,且configList.add("a")也合法 - 若需彻底不可变,应配合不可变容器(如
java.util.Collections.unmodifiableList())或使用ImmutableList(Guava) - 常见误用:以为 final List 就是只读配置,实际仍可能被意外修改
配合 static 实现类级常量配置
大多数配置场景需要全局唯一、无需实例化的常量,此时 public static final 是标准写法。
- 命名习惯:全大写+下划线,如
DB_URL、DEFAULT_TIMEOUT_MS - 值通常来自字面量、静态计算(如
Math.PI)或安全的静态工厂方法 - 避免在 static final 中调用可能抛异常或依赖未初始化资源的方法,否则类加载会失败
替代方案:当需要“逻辑上可配置但运行时不可改”时
如果配置需从外部(如 properties 文件、环境变量)加载,又希望加载后锁定,可用私有 final 字段 + 静态初始化块封装:
- 声明
private static final String API_KEY; - 在 static 块中读取配置并赋值:
API_KEY = loadFromEnv("API_KEY"); - 确保
loadFromEnv方法幂等、无副作用,且只执行一次 - 对外提供 public static getter,不暴露 setter 或可变引用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











