Bootstrap

string数组怎么赋值_String类可变?真的吗?

d2af833206699ef211ec6056ad90816a.png

都说String是不可变的,但是究竟哪里不可变,是内容不可变还是什么不可变,又是怎么个变法,对此真的头大!为此我苦思不得其解,终于让我找到梗了!

首先我看了String源码,String被final修饰,而String类内的方法也都是被final修饰的。众所周知String底层是char数组,这个数组继而也是被final修饰。  

一旦被final修饰,其初始化后内容是不可变的。数组被final修饰,数组长度是不可变的。  

在IDE编辑器,Ctrl+N找到String类源码,再Ctrl+Alt+O,会出现以下信息,提示String是只读的,不能被修改。(这里的快捷键以自己配置的快捷键为主)

3e556e439cab6bf5a6dcc29e30ed4007.png

从上所述可得出: String 类的不可变真相,对于String类来说,不可变有两点含义:  

1.字符串长度不可变,这是由于底层是char[]数组决定的。  

2.字符串内容不可变,这是由于String类没有提供修改内容的方法导致的。  

但是String又是可变的,怎么个变法呢? 

下面我先抛出一个案例:  

String str = "花夕";
str = "花兮你好";
System.out.println(str);

运行结果是:

b60bd078068ae09d76013cc06acf8c17.png

由上面的案例可以看出str由“花夕”变成了“花夕你好”,这个str变了呀,其实懂String的人都知道,在声明str字符串的时候只是声明的一个地址而已,当你改变它的值的时候,不是重新给它赋值,而是重新申请了一个地址,存储”花夕你好”,srt引用指向存储”花夕你好”的地址而已。   

上面都讲的是String定义的字符串不可变,内容不可变,但是我就是想尝试一下让它变化。  

1.我用我学过的反射改变String定义的字符串内容,静观其变。

String str = "花夕";
System.out.println("str未被修改的值是:" + str);//通过反射从方法区内存空间获取String类相关信息
Class clazz = String.class;//获取String类里的value字段
Field f = clazz.getDeclaredField("value");//绕过正常访问机制,增加访问权限,可以被修改
f.setAccessible(true);//获取str属性值char[] chars = (char[]) f.get(str);//给str值重新赋值,改变的还是原来的char[]数组
chars[0] = 'h';
chars[1] = 'x';
System.out.println("str被修改后的值" + str);

运行结果: 

263f6c65374b38700a2f421f95d10ce4.png

哇,str真的被修改过来了,好神奇哦。  

2.我再看看String定义的字符串长度可变不?

我在上面的代码基础上加上一行代码

chars[2] = 'n';

运行结果:

ad88f6f4eeb577cb321e0215ff11eda1.png

直接报错,看来String定义的字符串长度是不可以变的哦。

看完这篇文章,你对String类到底可变有了一定认识了吧!

如果在找工作中,面试官问你String类可变不可变,你说一下。你就可以直接把这篇文章搬过去,相信面试官对你会刮目相看的!

推荐阅读:

为什么鲜有炫富的程序员?

开猿节流?可把我开心死了!

c5a6854a167c3c0296a57fbc80e5bfda.png

今日话题:String类到底可变不可变!

;