[英]Cannot change static final field using java reflection?
我最近偶然發現了使用Java反射的Change private static final字段,並測試了polygenelubricants的EverythingIsTrue
類,可以正常工作, System.out.format("Everything is %s", false);
打印Everything is true
。 但是當我將代碼更改為
public class EverythingIsTrue {
public static final boolean FALSE = false;
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(EverythingIsTrue.class.getField("FALSE"), true);
System.out.format("Everything is %s", FALSE);
}
}
它打印
Everything is false
有人知道為什么嗎? setFinalStatic是否實際起作用?
通過使值成為方法調用的結果(甚至是虛擬調用),可以避免編譯器內聯。
public class Main {
// value is not known at compile time, so not inlined
public static final boolean FLAG = Boolean.parseBoolean("false");
static void setFinalStatic(Class clazz, String fieldName, Object newValue) throws NoSuchFieldException, IllegalAccessException {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiers = field.getClass().getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String... args) throws Exception {
System.out.printf("Everything is %s%n", FLAG);
setFinalStatic(Main.class, "FLAG", true);
System.out.printf("Everything is %s%n", FLAG);
}
}
版畫
Everything is false
Everything is true
當訪問原始靜態final字段時,Java編譯器將假定該值是一個常量,並內聯該值,而不是生成訪問該字段的代碼。 這意味着編譯器將使用值為false
對FALSE
字段的引用替換。 如果使用反射來訪問該字段,您將看到該字段的值實際上已更改。
這不適用於非基本字段,因為在編譯時無法內聯對象引用的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.