簡體   English   中英

無法使用Java反射更改靜態最終字段?

[英]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編譯器將假定該值是一個常量,並內聯該值,而不是生成訪問該字段的代碼。 這意味着編譯器將使用值為falseFALSE字段的引用替換。 如果使用反射來訪問該字段,您將看到該字段的值實際上已更改。

這不適用於非基本字段,因為在編譯時無法內聯對象引用的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM