string变成char数组_String类可变?真的吗?

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

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

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

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

521f592f1ec5b91bf8ef6d6eabf912c4.png

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

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

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

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

下面我先抛出一个案例:

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

运行结果是:

78f1896e655342334e2e01aa151786fd.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);

运行结果:

606086cd392e894a7372dd3f4ffefd97.png

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

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

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

chars[2] = 'n';

运行结果:

37c4c4d9b45488783eedac10c78fcb9c.png

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

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

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

【转发】和【关注】是对小强最大的支持!!!

c870778de25d0dd2fad224cd1b4b9500.png
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值