栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的String为什么是不可变的?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的String为什么是不可变的?

首先需要补充一个知识点:对于基本数据类型来说,

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

浏览器打开:qq.cn.hn/FTf 开源分享

用final修饰后,我们就说当前变量不能重新赋值,因此基本数据类型,是不可改变。但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用变量所引用的地址不会改变,即一直引用同一个对象,但这个对象中成员变量或者数组完全可以发生改变。例如某个指向数组的final引用,它必须从此至终指向初始化时指向的数组,但是这个数组的内容完全可以改变。

在java中,String保存值的两个重要成员变量,其中value指向的是一个字符串数组,字符串中的字符就是用这个value变量存储起来的,并且用final修饰,也就是说value一旦赋予初始值之后,value指向的地址就不能再改变了。虽然value指向的数组的值是可以改变的,但是String也没有提供相应的方法让我们去修改value指向的数组的元素。然而在StringBuilder中是提供了相应的方法让我们去修改value指向的数组的元素,这也是StringBuilder的字符串序列可变的原因。可见图如下:

具体实例,并且配图分析:

运行结果:

程序分析:

str1+=str2实际上是执行了str1=(new StringBuilder()).append(str2).toString();前后实际额外产生了一个StringBuilder与一个HelloWord的字符串常量。str1执行+=前后内存的示意图如下所示:

String对象真的不可变吗?

虽然value是final修饰的,只是说明value不能再重新指向其他的引用。但是value指向的数组可以改变,一般情况下我们是没有办法访问到这个value指向的数组的元素。但是可以使用反射,可以反射出String对象中的value属性, 进而改变通过获得的value引用改变数组的结构。

String str = “Hello World”;

System.out.println(“修改前的str:” + str);

System.out.println(“修改前的str的内存地址” + System.identityHashCode(str));

// 获取String类中的value字段

Field valueField = String.class.getDeclaredField(“value”);

// 改变value属性的访问权限

valueField.setAccessible(true);

// 获取str对象上value属性的值

char[] value = (char[]) valueField.get(str);

// 改变value所引用的数组中的字符

value[3] = ‘?’;

System.out.println(“修改后的str:” + str);

System.out.println(“修改前的str的内存地址” + System.identityHashCode(str));

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/571579.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号