跳到主要内容

🍬修改 final 常量的值

在 Java 语言中,使用 final 关键字修饰的变量叫做常量,因为它不允许再次被赋值。但这不是绝对的,因为这一限制只发生在编译时期。


在声明变量时,使用 final 关键字本质上是告诉 Java 编译器,这个变量初始化后不允许被修改。当尝试修改这个变量时,编译器会报错,这一切都是编译器在"搞鬼",发生在编译时期。

如果说 Java 是一个纯粹的静态语言的话,那么这个特殊的变量就是真正的常量了,只要编译时不允许修改,那就真的不能修改了。

但是 Java 可以通过反射,在运行时对这个"常量"做一些手脚。

public class Sugar {
// 要修改的变量
final int target = 10;

public static void main(String[] args) throws Exception {
Sugar sugar = new Sugar();

Class<? extends Sugar> clazz = sugar.getClass();
Field targetField = clazz.getDeclaredField("target");
// 打印修改前的值
int oldVal = targetField.getInt(sugar);
System.out.println("old value: " + oldVal); // 10
// 修改值
targetField.setAccessible(true);
targetField.set(sugar, 20);
// 打印修改后的值
int newVal = targetField.getInt(sugar);
System.out.println("new value: " + newVal); // 20
}
}

这么做其实没有什么实际意义,只是对编译时和运行时有个理解。