图说:为什么Java中的字符串被定义为不可变的
转载自 图说:为什么Java中的字符串被定义为不可变的
字符串,想必大家最熟悉不过了,通常我们在代码中有几种方式可以创建字符串,比如:String s = "Hollis";
这时,其实会在堆内存中创建一个字符串对象,其中保存了一个字符数组,该数组中保存了字符串的内容。
上面的箭头可以理解为“存储他的引用”。
当我们在代码中连续创建两个相同的字符串的时候,其实会指向同一个对象。因为当一个字符串被被创建的时候,首先会去这个字符串池中查找,如果找到,直接返回对该字符串的引用。
但是,如果在程序中明确声明要新创建一个字符串的话是可以在堆上重新创建一个对象的。如String s = new String("Hollis")
接着,我们来看两个字符串中常用的操作:截取和连接会发生什么,是在原来的字符串对象上修改还是重新创建字符串呢?
字符串的连接。如String s1 = s.concat("Chuang");
字符串的截取。如String s1 = s.substring(0,2);
从上图中我们可以得到一个结论,那就是——字符串是不可变的,无论发生什么操作,一个已经创建好的字符串的内容不会被改变,对它的任何类似修改的操作其实都是新生成了一个字符串对象。
那么,为什么要定义出不可变对象呢?
缓存Hashcode
Java中经常会用到字符串的哈希码(hashcode)。例如,在HashMap中,字符串的不可变能保证其hashcode永远保持一致,这样就可以避免一些不必要的麻烦。这也就意味着每次在使用一个字符串的hashcode的时候不用重新计算一次,这样更加高效。
在String类中,有以下代码:private int hash;
以上代码中
hash
变量中就保存了一个String对象的hashcode,因为String类不可变,所以一旦对象被创建,该hash值也无法改变。所以,每次想要使用该对象的hashcode的时候,直接返回即可。
使其他类的使用更加便利
在介绍这个内容之前,先看以下代码:
在上面的例子中,如果字符串可以被改变,那么以上用法将有可能违反Set的设计原则,因为Set要求其中的元素不可以重复。上面的代码只是为了简单说明该问题,其实String类中并没有value
这个字段值。
安全性
String被广泛的使用在其他Java类中充当参数。比如网络连接、打开文件等操作。如果字符串可变,那么类似操作可能导致安全问题。因为某个方法在调用连接操作的时候,他认为会连接到某台机器,但是实际上并没有(其他引用同一String对象的值修改会导致该连接中的字符串内容被修改)。可变的字符串也可能导致反射的安全问题,因为他的参数也是字符串。
不可变对象天生就是线程安全的
因为不可变对象不能被改变,所以他们可以自由地在多个线程之间共享。不需要任何同步处理。
总之,String
被设计成不可变的主要目的是为了安全和高效。所以,使String
是一个不可变类是一个很好的设计。
图说:为什么Java中的字符串被定义为不可变的相关推荐
- 同一个字符串hash值相同吗_图说:为什么Java中的字符串被定义为不可变的
原文地址:https://dwz.cn/zWeX9Z7k 作者:Hollis 文章来源:微信公众号 字符串,想必大家最熟悉不过了,通常我们在代码中有几种方式可以创建字符串,比如:String s = ...
- [转载] Java中的字符串处理
参考链接: Java中的StringBuffer appendCodePoint()方法以及示例 JDK8在线Api中文手册 JDK8在线Api英文手册 Java中的字符串处理 1.1 String类 ...
- 检查Java中的字符串是空还是空[重复]
本文翻译自:Checking if a string is empty or null in Java [duplicate] This question already has an answer ...
- Java中的字符串驻留
转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = "hello" + ...
- java oracle 连接字符串函数_通过shell来比较oracle和java中的字符串使用
这些准备工作齐了之后,我们来从Java中的字符串使用入手来比较一下oracle中对于字符串的处理. java中有如下的一些函数,我会依次来做比较. public char charAt(int ind ...
- Java中连接字符串的最佳方法
最近有人问我这个问题–在Java中使用+运算符连接字符串是否对性能不利? 这让我开始思考Java中连接字符串的不同方法,以及它们如何相互对抗. 这些是我要研究的方法: 使用+运算符 使用StringB ...
- java 匹配最后一次出现的字符_在Java中查找字符串中字符的最后一次出现
使用该lastIndexOf()方法在Java中查找字符串中字符的最后一次出现. 假设以下是我们的字符串.String myStr = "Amit Diwan"; 在上面的字符串中 ...
- java 保留字符串,如何在Java中保留字符串而不使用反转功能
有以下几种在Java中反转字符串的方法: 使用for循环 使用While循环 使用静态方法 使用For循环 使用for循环在Java中反转字符串的示例 在下面的示例中, 我们使用了for循环来反转字符 ...
- Android学习笔记----Java中的字符串比较
用习惯了C#.C++,在做字符串比较时想当然地使用如下语句: 1 string str1 = "abcd", str2 = "abcd"; 2 if(str1= ...
最新文章
- 硕士生两年发14篇论文!获浙大最高层次奖学金!
- Ajax实现局部数据交互的一个简单实例
- CentOS7.3的基本配置(建议学习用)
- 【修饰符】四种访问修饰符和各自的权限
- 【渝粤题库】广东开放大学 静态网页技术 形成性考核
- 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 6丨统计各专业学生人数【难度中等】
- Bailian4101 晶矿的个数【DFS】
- HP推出UFT新版本UFT12 5以及LeanFT
- 逆向研究QCA9563固件,查看和修改GPIO定义
- 梅科尔工作室-李庆浩-网页前端7
- 微信公众号文章编辑排版工具+自动采集+使用视频教程
- Excel技能培训之四-按颜色排序,按自定义文字排序
- 全球三大计算机病毒爆发事件,全球爆发勒索病毒 十大恐怖电脑病毒排行榜(3)...
- b站《史上最全unity3D教程》笔记1-04
- YOLOv5全面解析教程③:更快更好的边界框回归损失
- 如何用邮件(微信)接收交易信号?
- 【时间序列】季节性问题
- 机器学习(线性模型)
- C语言--入门程序hello world
- CRM系统一定要选一家靠谱的公司
热门文章
- [汇编语言]实验:更灵活的寻址方式 -应用si和di
- C++文本文件操作和二进制文件读写
- [USACO1.5]八皇后 Checker Challenge
- Mayor's posters POJ - 2528 (离散化+线段树)
- 石家庄学院c语言试题,谁会高级语言程序设计?要求用C语言,帮帮我把,愁死我啦...
- 空心点_空心砖的新玩法,看完大开眼界
- jdicom怎么做虚拟服务器,jdicom使用手册
- GPU Shader 编程基础
- TCP协议——流量控制和拥塞控制
- Codeforces Round #212 (Div. 2) C. Insertion Sort 思维