问题
Can a package final variable be changed through reflection?
Say I have this:
public class Widget {
final int val = 23;
}
Can the val be changed through reflection if made accessible?
If so, is there any way to prevent it that without using the security manager?
回答1:
Turns out, changing final members causes reflection-obtained values to differ from values returned by regular code! This is quite scary.
import java.lang.reflect.Field;
public class Test {
private static final class Widget {
private final int val = 23;
public int getVal() {
return val;
}
}
public static void main(String[] args) throws Exception {
Widget w = new Widget ();
Field m = Widget.class.getDeclaredField("val");
m.setAccessible(true);
m.set(w, 233);
Field m1 = Widget.class.getDeclaredField("val");
m1.setAccessible(true);
System.out.println(m.get(w)); /// PRINT 233
System.out.println(w.getVal()); /// PRINT 23
System.out.println(m1.get(w)); /// PRINT 233
}
}
回答2:
YES. Try this code:
public static void main(String[] args) throws Exception {
Widget w = new Widget ();
Field m = Widget.class.getDeclaredField("val");
m.setAccessible(true);
m.set(w, 233);
System.out.println(m.get(w)); /// PRINT 233
}
回答3:
Try this.
Widget() {
checkPerMission();
}
private void checkPerMission() {
Class self = sun.reflect.Reflection.getCallerClass(1);
Class caller = sun.reflect.Reflection.getCallerClass(3);
if (self != caller) {
throw new java.lang.IllegalAccessError();
}
}
来源:https://stackoverflow.com/questions/23894354/can-a-package-final-variable-be-changed-through-reflection