【发布时间】:2015-03-15 11:42:17
【问题描述】:
听起来可能有点奇怪,但是可以在运行时添加final 修饰符吗?
我有一个标记为public static int/short 的变量。在某些时候,我想防止更改它的值,并且我想将其可访问性保持为标准静态值 (ClassName.field)。
public class Main {
private static int a = 0;
public static void addFinalMod(Field f) {
Field modifiersField = null;
try {
modifiersField = Field.class.getDeclaredField("modifiers");
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
modifiersField.setAccessible(true);
try {
modifiersField.setInt(f, f.getModifiers() & Modifier.FINAL);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println(a);
try {
Field f = Main.class.getDeclaredField("a");
addFinalMod(f);
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
a = 10; //I was expecting error/exception here
System.out.println(a);
}
输出:
0
10
【问题讨论】:
-
其实这是一个非常有趣的问题。目前,对我来说,
final规则似乎只在编译时检查(这包括初始化要求和 JMM 保证)。 -
我认为您的意思是
f.getModifiers() | Modifier.FINAL而不是f.getModifiers() & Modifier.FINAL让其他修饰符保留。此外,如果您使用f.set(null, 5);,您将获得预期的异常。