![](/img/trans.png)
[英]Set private field with reflection works on static OR final, but not static final (combined)
[英]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.