通过反射改变String类的值

通常认为String类对象是不可修改的,例如:
String s="abc";
s="123";
System.out.println(s);

首先创建一个String对象s,然后让s的值为“abc”, 然后又让s的值为“123”。 从打印结果可以看出,s的值确实改变了。


这里的s只是一个String对象的引用,并不是对象本身。
对象在内存中是一块内存区,成员变量越多,这块内存区占的空间越大。引用只是一个4字节的数据,里面存放了它所指向的对象的地址,通过这个地址可以访问对象。 也就是说,s只是一个引用,它指向了一个具体的对象,当s=“123”; 这句代码执行过之后,又创建了一个新的对象“123”, 而引用s重新指向了这个新的对象,原来的对象“abc”还在内存中存在,并没有改变。


String 类的成员对象有
private final char[] value;
private final int offset;
private final int count;

value,offset和count这三个变量都是private的,并且没有提供setValue, setOffset和setCount等公共方法来修改这些值,所以在String类的外部无法修改String。也就是说一旦初始化就不能修改, 并且在String类的外部不能访问这三个成员。此外,value,offset和count这三个变量都是final的, 也就是说在String类内部,一旦这三个值初始化了, 也不能被改变。
所以可以认为String对象是不可变的了。


但,可以通过反射改变String value的值

        String s = "abcd";       
    System.out.println("s = " + s); //修改前     
    //获取String类中的value字段
    Field valueField = String.class.getDeclaredField("value");     
    //改变value属性的访问权限
    valueField.setAccessible(true);      
    //获取s对象上的value属性的值
    char[] value = (char[]) valueField.get(s);       
    //改变value所引用的数组中的第5个字符
    value[3] = 'e';      
    System.out.println("s = " + s);  //修改后              
    //改变整个字符串
    valueField.set(s, new char[]{'1', '2', '3'});       
    //特别注意这里,因为改变了value的值,字符串长度已经改变了,需要同时改变count的值,不然使用s时会报数组越界
    Field countField = String.class.getDeclaredField("count");
    countField.setAccessible(true);
    countField.set(s, 3);
    System.out.println("s = " + s);  //123

特别注意

通过发射修改String的值的时候,特别要注意维护好count的值,因为修改后的字符串长度可能已经改变。看String源码,length方法就是返回count的值。如下:

public int length() {
    return this.count;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,949评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,766评论 18 399
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,518评论 0 3
  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,771评论 0 33
  • 今晚依然感觉会失眠,盯着天花板,天花板也没有让我失望不一会儿就出现了你的脸颊。好想你,现在的你睡着了么?想打你电话...
    jryc阅读 153评论 0 0