java中的String字符串详解

本文介绍了Java中的常量池,包括字符串常量池在Java 8后放于堆中,运行时常量池在元空间。阐述了使用字符串常量池和new创建字符串的机制,并通过示例说明不同创建方式下字符串地址比较结果。还对比了String、StringBuffer、StringBuilder的可变与不可变、线程安全性和执行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常量池:
静态常量池:指的是编译时常量池,我们不关注
字符串常量池:在java8之后放在了堆里
运行时常量池:放在了元空间里,元空间放在了主存里(不在堆里了,不占有jvm内存空间)

使用字符串常量池(也就是当我们用类似String a = “xiaoming”;)。每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串!

但当我们使用new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后放池里一份(所以new一般是new两个对象),然后返回堆中的地址。

举个例子来理解String字符串:

String a = “xiaoming”;
final String m = “xiao”;
final String n = “ming”;
String b = “xiao”;
String c = “ming”;
String d = “xiao” + “ming”;
String e= b + c;
String f = m+n;
String g = new String(“xiaoming”);
System.out.println((a == d));
System.out.println((a == e));
System.out.println((a == f));
System.out.println((a == g));

输出结果:
true
false
true
false

首先,==比的都是地址,第一种情况下,由于编译期会优化,优化后的 d = “xiaoming”,由于字符串常量池的原因,d会指向已经创建好的a,所以地址不变返回true。

第二种情况,JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,所以会新建一个变量,a和e的地址就不相同了,返回true。

第三种情况,被final修饰后的变量不可再赋值,所以会返回true。

第四种情况,最常见,直接新建一个变量在堆里,二者地址显然不同,返回false。

String、StringBuffer、StringBuilder的区别

(1)可变与不可变:String是不可变字符串对象,StringBuilder和StringBuffer是可变字符串对象(其内部的字符数组长度可变)。

(2)是否多线程安全:String中的对象是不可变的,也就可以理解为常量,显然线程安全。StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是StringBuffer 中的方法大都采用了synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是非线程安全的。

(3)String、StringBuilder、StringBuffer三者的执行效率:
StringBuilder > StringBuffer > String 当然这个是相对的,不一定在所有情况下都是这样。比如String str = “hello”+ "world"的效率就比 StringBuilder st = new StringBuilder().append(“hello”).append(“world”)要高。因此,这三个类是各有利弊,应当根据不同的情况来进行选择使用:
当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;
当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值