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/

  

Java反射之修改常量值的更多相关文章

  1. Android利用Java反射机制修改Android System Language

    private void updateLanguage(Locale locale) { try { Object objIActMag, objActMagNative; Class clzIAct ...

  2. Java 反射修改类的常量值、静态变量值、属性值

    前言 有的时候,我们需要修改一个变量的值,但变量也许存在于 Jar 包中或其他位置,导致我们不能从代码层面进行修改,于是我们就用到了下面的场景,通过反射来进行修改变量的值. 定义一个实体类 class ...

  3. Java反射-修改private final成员变量值,你知道多少?

    大家都知道使用java反射可以在运行时动态改变对象的行为,甚至是private final的成员变量,但并不是所有情况下,都可以修改成员变量.今天就举几个小例子说明.  基本数据类型 String类型 ...

  4. JAVA反射改动常量,以及其局限

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/barryhappy/article/details/24442953 问题,以及一个解决方式 今天公 ...

  5. java反射新的应用

    利用java反射动态修改运行中对象的私有final变量,不管有没有get方法获取这个私有final变量. spring aop 本质是cglib,动态代理 可以做很多事情 query.addCrite ...

  6. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  7. Java反射-修改字段值, 反射修改static final修饰的字段

    反射修改字段 咱们从最简单的例子到难, 一步一步深入. 使用反射修改一个private修饰符的变量name 咱们回到主题, 先用反射来实现一个最基础的功能吧. 其中待获取的name如下: public ...

  8. Java 常量值的数据类型

    Java 常量值(也叫字面量)和变量一样,也是有数据类型的. 经常有面试题考察你对 Java 常量值数据类型的理解,如下: float a = 3.3; 问你这一行代码是否正确?答案肯定是不正确.为什 ...

  9. 如何修改const常量值

    总结:这个跟计算机语言类别和编译器有关,本文是在linux环境下说明的. 分两种情况: 1. C语言: 2. C++语言: /*! * \Description: * \author scictor ...

随机推荐

  1. Cocos2D iOS之旅:如何写一个敲地鼠游戏(六):放置地鼠

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  2. Android版本更新时对SQLite数据库升级或者降级遇到的问题

    SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定 ...

  3. 【Unity Shaders】Transparency —— 使用alpha通道创建透明效果

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  4. 通过一个工具类更深入理解动态代理和Threadlocal

    动态代理和Threadlocal 一个代理类返回指定的接口,将方法调用指定的调用处理程序的代理类的实例.返回的是一个代理类,由指定的类装载器的定义和实现指定接口指定代理实例调用处理程序最近用到一个工具 ...

  5. ffmpeg转码器移植VC的工程:ffmpeg for MFC

    本文介绍一个自己做的FFMPEG移植到VC下的开源工程:ffmpeg for MFC.本工程将ffmpeg工程中的ffmpeg转码器(ffmpeg.c)移植到了VC环境下.并且使用MFC做了一套简单的 ...

  6. Java:函数

    import java.util.Scanner; public class HelloWorld { public static void main(String[] args){ Scanner ...

  7. wordpress入门基础:wordpress文件系统结构详细介绍

    根目录|| wp-admin — wp-content — wp-includes|                    | |___________________________________ ...

  8. 开源摄影机:Axiom Camera

    一般情况下只有软件才有开源这个概念.这会儿发现了个很厉害的开源的产品:开源摄影机. 我还是第一次听说摄影机也可以开源.于是去该产品的官方网站了解了一下相关信息. 官网:http://axiom.ape ...

  9. Python学习笔记 - 生成器generator

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # generator 生成器 L = [x * x for x in range(10)] print( ...

  10. Dynamics CRM 请求服务时报access is denied错误

    在javascript脚本里使用ODATA向组织服务发请求时报错,请求被拒绝了,后经人点拨得知是脚本跨域的问题,原因如下:访问系统我用的是IP地址,但通过 Xrm.Page.context. cont ...