当前位置: 首页 > news >正文

反射无法修改 final String

文章目录

      • 1. Demo
      • 2. String 为什么不能被修改?
      • 3. 参考资料

1. Demo

### Demo
public class Demo {

    public static void main(String[] args) {
        User user = new User();
        Class<User> clz = User.class;
        Field field1 = null;
        try {
            // 修改 String 对象失败
            field1 = clz.getDeclaredField("name");
            field1.setAccessible(true);
            field1.set(user, "xixi");
            
            // 修改 Student 对象成功
            field1 = clz.getDeclaredField("student");
            field1.setAccessible(true);
            field1.set(user, new Student());
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}


### User
class User {
    private final String name = "Bob";
    private final Student student = new Student();

    public String getName() {
        return name;
    }

    public Student getStudent() {
        return student;
    }
}
  • 经过测试,Student 变量即使被 final 修饰也是可以通过反射进行修改的,但是 String 变量没有修改成功

2. String 为什么不能被修改?

  • 对应的 User.class 文件
class User {
    private final String name = "Bob";
    private final Student student = new Student();

    User() {
    }

    public String getName() {
        return "Bob";
    }

    public Student getStudent() {
        return this.student;
    }
}
  • 这就涉及到 JVM 的内联优化了

内联函数,编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支

  • 简单的说,就是JVM在处理代码的时候会帮我们优化代码逻辑,比如上述的 final 变量,已知 final 修饰后不会被修改,所以获取这个变量的时候就直接帮你在编译阶段就给赋值了
  • 所以上述的 getName 方法经过 JVM 编译内联优化后会变成:
public String getName() {
    return "Bob";
}
  • 所以无论怎么修改,都获取不到修改后的值
  • 总结:反射是可以修改final变量的,但是如果是基本数据类型或者String类型的时候,无法通过对象获取修改后的值,因为JVM对其进行了内联优化
  • 那有没有办法获取修改后的值呢?有,可以通过反射中的 Field.get(Object obj) 方法获取:
// 获取 field 对应的变量在 user 对象中的值
System.out.println("修改后" + field.get(user));

3. 参考资料

  • https://blog.csdn.net/afdafvdaa/article/details/115190755
  • https://www.51cto.com/article/641671.html

相关文章:

  • 上海 网站建设业务营销方法/网络营销渠道策略有哪些
  • 网站设计模板素材/油烟机seo关键词
  • 建设在线购物网站/百度seo是啥意思
  • 免费下载教学设计的网站/香飘飘奶茶软文
  • 最简单的编程语言/北京seo推广公司
  • 独立做网站需要学习什么/百度官方客服电话
  • Powershell渗透框架
  • 探究SQL SERVER 更改跟踪
  • 软件测试面试,如何自我介绍?
  • 《Linux Shell脚本攻略》学习笔记-第三章
  • Fedora 37 编译安装opencv 4.7.0 —— 筑梦之路
  • 阿里巴巴2018届应届生在线编程测验记录-研发工程师C/C++
  • Modern C++ | 谈谈万能引用以及它的衍生问题:将亡值、引用折叠和完美转发
  • linux挂载新磁盘
  • 安科瑞能耗监测系统在新疆昌吉市政务中心项目的研究与应用
  • 交互与前端20 APIFunc.DataBase监控
  • ck的array函数
  • 华为机试题:HJ11 数字颠倒(python)