簡體   English   中英

Java Reflection,更改私有靜態final字段沒有做任何事情

[英]Java Reflection, change private static final field didn't do anything

我正在嘗試使用Java Reflection更改私有靜態final字段。 但它只是失敗了。 有人有想法嗎?

這是我的代碼:

public class SecuredClass {
    private static final String securedField = "SecretData";
    public static String getSecretData() { return securedField; }
}

public class ChangeField {
    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
    {
        System.out.println("Before = " + SecuredClass.getSecretData());

        Field stringField = SecuredClass.class.getDeclaredField("securedField");
        stringField.setAccessible(true);
        setFinalStatic(stringField, "Screwed Data!");


        System.out.println("After = " + Java_FileMerger_Main.getSecretData());
    }
}

這是我的輸出:

Before = SecretData
After = SecretData

我試圖用System.setSecurityManager(null)刪除SecurityManager; 但它沒有改變任何東西。 我知道這是邪惡的,但我想讓它發揮作用。 我希望有人可以幫助我。

通過反射改變最終字段的語義沒有定義(參見規范 )。 不能保證在從場上讀取時會看到對最終場的反射寫入。

特別是對於具有常量分配的靜態final字段(如在您的情況下),編譯器通常會內聯常量,因此在運行期間根本不會訪問該字段(僅當您使用反射時)。

SecurityManager與此處無關。 如果SecurityManager禁止使用反射,則操作將拋出異常,並且不會以靜默方式失敗。

問題的答案使用Java反射更改私有靜態最終字段提供了一些更多細節,包括一個示例,您可以在字節代碼中看到常量被內聯。

我也遇到了上面給出的例子的問題。 對我來說,在我沒有將String定義為文字而是將其定義為Object之后,它才起作用。

private static final String SECURED_FIELD = String.valueOf("SecretData");

要么

private static final String SECURED_FIELD = new String("SecretData");

如果你想從文字中受益,這不是最好的解決方案,但我不必關心它。

有一個解決方案。 如果你在static {}塊中設置private static final字段的值,它將起作用,因為它不會內聯字段:

private static final String MY_FIELD;

static {
    MY_FIELD = "SomeText"
}

...

Field field = VisitorId.class.getDeclaredField("MY_FIELD");

field.setAccessible(true);
field.set(field, "fakeText");

暫無
暫無

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

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