Java反射,更改私有静态最终字段没有做任何事情

Nicnl:

我正在尝试使用Java Reflection更改私有的static 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;但这并没有改变任何东西。我知道这很邪恶,但是我想让它正常工作。我希望有人可以帮助我。

菲利普·温德勒:

通过反射更改最终字段的语义未定义(请参阅Specification)。不能保证从该字段读取时会看到对最终字段的反射写入。

尤其是对于分配了常量的静态final字段(如您的情况),编译器通常会内联该常量,因此在运行时根本不会访问该字段(仅当您使用反射时)。

SecurityManager在这里不相关。如果SecurityManager禁止使用反射,则该操作将引发异常,并且不会无提示地失败。

使用Java反射更改私有静态最终字段问题的答案提供了更多详细信息,包括一个示例,您可以在字节码中看到常量内联的示例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章