Java细节:为什么字符串是不可变的?

简介: Java细节:为什么字符串是不可变的?

我们想知道为什么字符串是不可变的,就要先理解字符串的概念

字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的,如s=“abcdefghij”,则s[0]=“a”。


为什么字符串是不可变的


上文我们可以知道字符串类似字符数组,既然是数组,我们就很容易想到数组在内存中的存储是连续的,即在定义数组时就分配了固定的地址和空间大小,那么字符串自然是不可变的。


1.前提条件?


字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。


2.字符串在内存中的存储

String a1 = "abc"; //字面量对象
String a2 = new String (abc);  //构造对象
String a3 = a1;

我们通过String创建对象a1,a2,a3,


a1存放的是abc这个值的地址,a1放在栈里边,对象a1指向abc的地址。

a1的值,放在字符串常量池中,而字符串常量池是堆中的一个特殊区域(这里解释一下jdk1.7才把字符串常量池放到堆里)。


a2是通过new一个对象创建的,它是在堆中另开辟一个新空间,JVM首先会对这个字面量(abc)进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池。

由于a1已经使字符串常量池中存在了abc,所以a2在堆中开辟的空间用来存储字符串常量池中abc的地址。


对a3来说,就是a3只拷贝了a1的地址,并没有拷贝a1的值,和上面所述的概念原理一样,大家可以输出a3.equals(a1)来进行检查就知道了。


逻辑如图:

20190217102314599.png


3.原因总结


字符串本质是数组,数组在创建时就开辟了一个连续地址,固定的空间的内存

字符串常量池实现的前提条件是Java中String对象是不可变的,字符串的值存放在字符串常量池中。

字符串不可变有一个优点就是编译器jet让字符串共享(字符串常量池),并且Java设计者认为共享带来的高效率远胜于提取、拼接字符串所带来的低效率。

目录
相关文章
|
1月前
|
安全 Java API
【Java字符串操作秘籍】StringBuffer与StringBuilder的终极对决!
【8月更文挑战第25天】在Java中处理字符串时,经常需要修改字符串,但由于`String`对象的不可变性,频繁修改会导致内存浪费和性能下降。为此,Java提供了`StringBuffer`和`StringBuilder`两个类来操作可变字符串序列。`StringBuffer`是线程安全的,适用于多线程环境,但性能略低;`StringBuilder`非线程安全,但在单线程环境中性能更优。两者基本用法相似,通过`append`等方法构建和修改字符串。
46 1
|
2天前
|
存储 移动开发 Java
java核心之字符串与编码
java核心之字符串与编码
10 2
|
9天前
|
Java
Java实现:将带时区的时间字符串转换为LocalDateTime对象
通过上述方法,你可以将带时区的时间字符串准确地转换为 `LocalDateTime`对象,这对于处理不需要时区信息的日期和时间场景非常有用。
174 4
|
19天前
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
|
24天前
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
|
1月前
|
存储 Java
|
1月前
|
存储 Java
如何在 Java 中打印字符串数组列表
【8月更文挑战第23天】
28 2
|
1月前
|
存储 Java API
|
1月前
|
Java 测试技术
Java系列之判断字符串是为空或者null
这篇文章介绍了如何在Java中使用`isEmpty()`方法判断字符串是否为空或`null`,并提供了相应的测试用例来演示其用法。