A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大蓝鲸Java 于 2017-3-16 16:33 编辑



【南京校区】毁人不倦篇之一 --- String真的是不变的吗?



        在我们平时Java的学习过程中,有一些常识性问题,我们都默守陈规的遵守了这些的原则,殊不知我们的Java是一个极具自由的语言,正如我们程序员的一样,放荡不羁爱自由。                在我们平时写一些代码的时候,如果多思考一下,往往会有一些出乎意料的答案产生。
        比如:毁人不倦篇之一 --- String真的是不变的吗?
        在我们平时的学习过程中有一个知识点,String和StringBuffer的区别。我们往往会认为StringBuffer是String的一个缓冲区。StringBuffer是可变的,而String是不可变的。
        但是我们确可以通过一些非正常手段来让String进行改变。
        首先,解释一下为什么平时我们会认为String是不可变的。在String的源码中String其实是以一个private final char value[];这样的数组将每一个字符存到一个名为value的数组中的。为final修饰,所以是这个数组的地址值不能发生改变。且此数组被private修饰,而String内部没有提供对这个数组修改的一些方法或者操作,所以我们不能在外界对这个数组进行修改。众所周知,如果我们得到一个数组的对象,是可以对这个数组的内部元素进行修改的。所以我们可以通过这个原理,让我们的String进行修改,打破常规!
        怎么样能获取到String类中的private 修饰的那个对象呢?这个就成为了关键。
        在Java中提供了一个技术叫做反射,在反射面前一切都是赤裸裸的。
              代码如下:
                String s = "abcd";//创建一个字符串对象
                Class clazz = s.getClass();//通过反射获取到String的字节码文件
                Field field = clazz.getDeclaredField("value");//得到私有的成员变量value
                field.setAccessible(true);//将私有权限消除
                char[] value = (char[]) field.get(s);//得到value数组的对象
                value[2] = 'Q';//将其中任意一个索引上的值变成另一个值
                System.out.println(s);//最终将字符串打印

        此时我们发现通过反射技术,可以实现字符串的改变!


1 个回复

倒序浏览
牛!  , 这个可以有!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马