Java反射之修改常量值

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"); //忽略final修饰符【注释一】
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();
}
}
}

2.1 注释一

public class FinalDemo {

    private static final Integer KEY = 12;

    public static void main(String[] args) throws NoSuchFieldException, SecurityException {
Field field = FinalDemo.class.getDeclaredField("KEY");
//getModifiers()以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。
System.out.println("private static final : "+Integer.toBinaryString(field.getModifiers())); //private static final : 11010
        System.out.println("---------------分割线-------------------");
System.out.printf("private : " + "%6s",Integer.toBinaryString(Modifier.PRIVATE) + "\n"); //private :    10
System.out.printf("static : " + "%6s",Integer.toBinaryString(Modifier.STATIC) + "\n"); //static  :  1000
System.out.printf("Final : " + "%6s",Integer.toBinaryString(Modifier.FINAL) + "\n"); //Final   : 10000
}
}

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/

  

上一篇:50个实用的jQuery代码段让你成为更好的Web前端工程师


下一篇:linq小知识总结