簡體   English   中英

反射替換靜態最終字符串

[英]Reflection for replace static final String

我完全按照以下方式使用反射:

反射

但每次我得到這個錯誤,我不知道為什么。

12-02 17:53:58.650: W/System.err(10646): java.lang.NoSuchFieldException: modifiers
12-02 17:53:58.650: W/System.err(10646):    at java.lang.Class.getDeclaredField(Class.java:631)
12-02 17:53:58.650: W/System.err(10646):    at com.example.ref.MainActivity.setFinalStatic(MainActivity.java:56)
12-02 17:53:58.650: W/System.err(10646):    at com.example.ref.MainActivity.onCreate(MainActivity.java:26)
12-02 17:53:58.650: W/System.err(10646):    at android.app.Activity.performCreate(Activity.java:5206)
12-02 17:53:58.650: W/System.err(10646):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1083)
12-02 17:53:58.650: W/System.err(10646):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
12-02 17:53:58.650: W/System.err(10646):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
12-02 17:53:58.650: W/System.err(10646):    at android.app.ActivityThread.access$600(ActivityThread.java:140)

我的代碼如下:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.i("aaa", "Before = " + securedField);
    try {
        Field stringField = MainActivity.class.getDeclaredField("securedField");
        stringField.setAccessible(true);
        setFinalStatic(stringField, new String("Screwed Data!"));
    } catch (Exception e) {
        e.printStackTrace();
    }
    Log.i("aaa", "After = " + securedField);
}

private 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);
}

有人知道問題出在哪里嗎? 謝謝!

看一下android版java.lang.reflect.Field的源代碼。

它沒有私有字段modifiers 相反,它看起來像這樣

public int getModifiers() {
    return accessFlags & 0xffff;  // mask out bits not used by Java
}

您嘗試將“普通”jvm的實現細節調整為android jvm。 因為它是另一個jvm的實現細節,所以它不適用於android。

但是你要做的事情無論如何都行不通。 請記住,編譯器會內聯常量。

這不行

class Greeting {

    public static final String SALUTATION = "Hello";

    public void greet(String name) {
        System.out.println(SALUTATION + " " + name);
    }
}

public class Main {

    public static void main(String[] args) throws Exception {
        Greeting greeting = new Greeting();
        greeting.greet("John");

        Field declaredField = Greeting.class.getDeclaredField("SALUTATION");
        setFinalStatic(declaredField, "Hey");

        greeting.greet("John");
    }

    private 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);
    }

} 

輸出將是

Hello John
Hello John

另請參閱JLS,13.4.9。 final字段和常量以獲取詳細信息。

暫無
暫無

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

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