改变Java String内容 - Go语言中文社区

改变Java String内容


改变Java String内容

1. 前言

从事Java开发的同学,或多或少都听说过这样一句话,String是不可变的,可你是否想过为什么?还有人认为String是可变的,因为我们在实际开发中,经常写出下面这样的代码,String的输出内容确是是改变了,这又是为什么呢?


// 代码0

String str = "hello"

str = "world";

System.out.println(str); // 输出world

在我们进入正题下,先解答下这个疑惑,这个清楚了,本篇的内容就很容易理解了!

代码0中,输出结果确实是显示了,我们改变了str的内容,可是String不是不可变的吗?首先我们要先弄清楚String的内部结构,String是一个final类,内部有一个private final char[] value;,这个value就是String存储核心(之前说过,详情请看深入浅出Java String)。而String是引用类型的,所以不可变的是value,而不是str引用,看下图就明白了:

string-change0

通过上图可以看到,我们只是改变来str的引用指向,并未改变源String的内容,所以我们常常所说的String不变,是指它的内容,即那个char value[]

2. 改变String

接下来进入正文,我们知道了String不可变是因为它内部的final char value[],那么现在就开始改变这个value[]

大家都知道final修饰的变量,一经赋值,就不允许在改变,但是在修饰数组时,我们却可以改变它的数组成员,看代码:


// 代码1

final int a = 1;

a = 2; // 编译错误

final char[] arr = {'h','e','l','l','o'};

char[] temp = {'w','o','r','l','d'};

arr = temp; // 编译错误

arr[0] = 't'; // 正确

arr[1] = 't'; // 正确

为什么会这样呢,因为final修饰的是char[] arr,所以这里的arr是个引用,即这个引用不能改变,而char[]的成员修改,不会影响到arr,所以是正确的。

讲到这里,我们就应该知道了如何修改String内部的value[]了,但是还面临一个问题,即value[]private的,这意味着只有它自己才能访问,但是我们可以用反射机制来打破它,强制修改私有成员!


// 代码2

String str = "hello";

Field value = String.class.getDeclaredField("value");// 获取String的value属性

value.setAccessible(true); //设置访问权限为true

char[] valueOfStr = (char[])value.get(str);//获取str上的value属性

valueOfStr[0] = 'Y'; //改变第一个字符

System.out.println(str); //输出Yello

代码2中,我们通过反射机制,打破来私有变量的访问规则,强制修改了str的内容。

3. 总结

了解了String的内部结构,通过反射机制我们也可以改变String的内容。但是,这里仅仅作为实验用,实际上不建议这样做,因为这样违背了封装性。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Sun1956/article/details/53168862
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-19 13:15:48
  • 阅读 ( 664 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢