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

GC算法介绍及工作原理和优缺点

前言

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

定义一个实体类

class Bean{  
    private static final Integer INT_VALUE = 100;  
}  

利用反射修改私有静态常量方法

System.out.println(Bean.INT_VALUE);  
Field field = Bean.class.getField("INT_VALUE");  
//将字段的访问权限设为true:即去除private修饰符的影响  
field.setAccessible(true);  
//去除final修饰符的影响,将字段设为可修改的 
Field modifiersField = Field.class.getDeclaredField("modifiers");  
modifiersField.setAccessible(true);  
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);  
//把字段值设为200  
field.set(null, 200);  
System.out.println(Bean.INT_VALUE);  

修改私有静态常量测试结果

100
200

看到测试结果说明我们的反射修改成功了。

利用反射修改共有静态变量方法

class Bean{  
    public static int nums = 100;
}  

System.out.println(Bean.nums);
Field field = Bean.class.getField(“nums”);
field.set(null, 200);
System.out.println(Bean.INT_VALUE);

测试结果修改成功。

100
200

奇怪的地方

注意到上述代码的中的静态常量类型是Integer,但是我们项目中实际需要修改的字段类型并不是包装类型Integer,而是java的基本类型int。
当把常量的类型改成int之后。

使用绝热演化/量子退火算法求解矩阵本征态

class Bean{  
    private static final int INT_VALUE = 100;//把类型由Integer改成了int  
}

在其他代码都不变的情况下,代码输出的结果竟然变成了诡异的:

100
100

而且在调试的过程中发现,在第二次输出的时候,内存中的Bean.INT_VALUE是已经变成了200,但是System.out.println(Bean.INT_VALUE)输出的结果却依然时诡异的100?!
是反射失效了吗?
又试了其他几种类型,发现这种貌似失效的情会发生在int、long、boolean以及String这些基本类型上,而如果把类型改成Integer、Long、Boolean这种包装类型,或者其他诸如Date、Object都不会出现失效的情况。

奇怪的原因

对于基本类型的静态常量,JAVA在编译的时候就会把代码中对此常量中引用的地方替换成相应常量值。
参考:Modifying final fields in Java
即对于常量 public static final int maxFormatRecordsIndex = 100

if( index > maxFormatRecordsIndex   ){  
    index  =  maxFormatRecordsIndex ;  
}  

这段代码在编译的时候已经被java自动优化成这样的:
if( index > 100){
index = 100;
}
所以在INT_VALUE是int类型的时候。

System.out.println(Bean.INT_VALUE);  

编译时会被优化成下面这样:
System.out.println(100);
所以,自然,无论怎么修改Boolean.INT_VALUE,System.out.println(Bean.INT_VALUE)都还是会依然固执地输出100了。
这本身是JVM的优化代码提高运行效率的一个行为,但是就会导致我们在用反射改变此常量值时出现类似不生效的错觉。

在 WPF 中使用 MahApps.Metro.IconPacks 提供的大量图标

给TA买糖
共{{data.count}}人
人已赞赏
经验教程

Azure Table Storage(一) : 简单介绍

2021-1-16 21:46:00

经验教程

GC算法介绍及工作原理和优缺点

2021-1-16 22:41:00

⚠️
免责声明:根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。 本站为个人博客非盈利性站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途,网站会员捐赠是您喜欢本站而产生的赞助支持行为,仅为维持服务器的开支与维护,全凭自愿无任何强求。本站部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。
无意侵害您的权益,请发送邮件至 momeis6@qq.com 或点击右侧 私信:momeis 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索