假设不SecurityManager阻止你这样做,你可以用setAccessible四处走动private并重置修改器以消除final,并实际修改private static final场。
下面是一个例子:
import java.lang.reflect.*;public class EverythingIsTrue {
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String args[]) throws Exception {
setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
}}
假设不SecurityException将引发上述代码打印。"Everything is true".
这里所做的实际工作如下:原始人
boolean价值
true和
false在……里面
main自动装箱为引用类型。
Boolean“常数”
Boolean.TRUE和
Boolean.FALSE
因此,随后每当
false自动装箱
Boolean.FALSE,它指的是相同的
Boolean指的是
Boolean.TRUE
一切
"false"现在是
"true"
相关问题
警告
当你做这样的事情时,应该格外小心。它可能不起作用,因为SecurityManager可能是存在的,但即使没有,取决于使用模式,它可能起作用,也可能不起作用。在某些情况下,例如反序列化,系统将需要更改final构造后对象的字段。final字段可以通过反射和其他依赖于实现的方法进行更改。具有合理语义的唯一模式是构造对象的模式,然后是final更新对象的字段。对象不应对其他线程可见,final字段,直到对final对象的字段是完整的。结冰final字段都出现在构造函数的末尾,其中final字段被设置,并且在每次修改final通过反射或其他特殊机制的场。
即使如此,也有许多复杂的问题。如果final字段初始化为字段声明中的编译时常量,则更改为final字段不能被观察到,因为它的用途final字段在编译时用编译时常数替换.
另一个问题是该规范允许对final田野。在线程中,允许重新排序final字段,并对构造函数中未发生的最后字段进行这些修改。
另见这种技术不太可能适用于原语
private static final boolean,因为它作为编译时常量是不可见的,因此“新”值可能是不可观测的。
附录:关于按位操作
基本上,field.getModifiers() & ~Modifier.FINAL
关闭对应于Modifier.FINAL从…field.getModifiers(). &是按位.而且.~是位补语。
另见
记住常量表达式
还是不能解决这个问题吗?,是否像我所做的那样陷入了抑郁?你的代码看起来像这样吗?
public class A {
private final String myVar = "Some Value";}
阅读了对这个答案的评论,特别是@pshemo的评论,它提醒了我常数表达式是不同的处理方式,所以不可能去修改它。因此,您需要将代码更改为如下所示:
public class A {
private final String myVar;
private A() {
myVar = "Some Value";
}}
如果你不是这个班的主人.。我感觉到你了!