1. 通过反射修改常量的值
package com.blueStarWei.invoke; import java.lang.reflect.Field; public class ModifyFinalField { private final Integer KEY_EXIT = 1024; private static void invoke() throws Exception{ ModifyFinalField mff = new ModifyFinalField(); System.out.println("Before modifying : "+mff.KEY_EXIT);//1024
//获取属性【private final java.lang.Integer com.blueStarWei.invoke.ModifyFinalField.KEY_EXIT】 Field field = mff.getClass().getDeclaredField("KEY_EXIT");
//忽略属性的访问权限 field.setAccessible(true);
//设置新的值 field.set(mff, 512); System.out.println("After modifying : "+mff.KEY_EXIT);//512 } public static void main(String[] args) { try { invoke(); } catch (Exception e) { e.printStackTrace(); } } }
2.通过反射修改静态常量的值
package com.blueStarWei.invoke; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class ModifyFinalField { private static final Integer KEY_EXIT = 1024; private static void invoke() throws Exception{ System.out.println("Before modifying : "+ModifyFinalField.KEY_EXIT);//1024
//获取属性【private final java.lang.Integer com.blueStarWei.invoke.ModifyFinalField.KEY_EXIT】 Field field = ModifyFinalField.class.getDeclaredField("KEY_EXIT"); //忽略访问权限
field.setAccessible(true); //忽略static修饰符【原理不明白】 Field modifiers = Field.class.getDeclaredField("modifiers"); modifiers.setAccessible(true); modifiers.setInt(field, field.getModifiers()&~Modifier.FINAL);
//设置新的值 field.set(null, 512); System.out.println("After modifying : "+ModifyFinalField.KEY_EXIT);//512 } public static void main(String[] args) { try { invoke(); } catch (Exception e) { e.printStackTrace(); } } }
3.注意事项
3.1 基本数据类型和String类型的final常量在编译时,编译器会自动将用到该常量的地方用实际值替换(不管是否是静态的);而封装类型不存在该现象。
static final int A = 23; if(i > A){ System.out.println(A); } //自动编译成 static final int A = 23; if(i > 23){ System.out.println(23); }
3.2 导致的问题:即使通过反射修改了基本数据类型和String类型的final常量的值,但是使用该常量时,值仍然是原来的值。
package com.blueStarWei.invoke; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class SpecialCase { private static final int NUM = 1024; private static void invok1() throws Exception { System.out.println("Before modify : "+SpecialCase.NUM);//Before modify : 1024 Field field = SpecialCase.class.getDeclaredField("NUM"); field.setAccessible(true); Field modifiers = Field.class.getDeclaredField("modifiers"); modifiers.setAccessible(true); modifiers.setInt(field, field.getModifiers()&~Modifier.FINAL); field.set(null, 512); //在下一行打断点,会发现NUM的值已经变为512,但是输出的仍然是1024 System.out.println("After modify : "+SpecialCase.NUM);//After modify : 1024 } public static void main(String[] args) { try { invok1(); } catch (Exception e) { e.printStackTrace(); } } }
更多内容,请访问:http://www.cnblogs.com/BlueStarWei/