String知识点整理
基础知识点
-
使用双引号创建字符串时,JVM会先在字符串常量池中查找是否已存在该字符串,存在则返回,不存在则在池中创建后再返回。使用String的
intern()
方法也是类似处理。 -
使用
new String
的方式创建,或者使用+
拼接变量时,JVM都会重新创建一个新对象。比如下面:String s1 = "1"; String s2 = "12"; String s3 = s1 + "2"; System.out.println(s2 == s3); // false
因为
s1
是引用变量,JVM在编译期不能确定s1
的值,所以会在堆中新创建一个对象指向s3
。如果s1
加个final
限制,让s1
能在编译阶段确定下来,它就是常量,因此在编译时,s1 + "2"
就会被优化成12。final String s1 = "1"; String s2 = "12"; String s3 = s1 + "2"; System.out.println(s2 == s3); // true
至于等号比较为什么相等,是因为
s2
已经在常量池中了,s3
被优化为了12,自然不会新创建了, 它跟s2
指向的是同一个对象。 -
new String("123")
创建了几个对象?一个或两个。先从常量池中查找123,有则创建,没有则不创建;new会新创建一个对象。
String为什么不可变
- 不能被继承;
- 未提供能改变它状态的公共方法;
- 它的工具方法都是返回一个新的字符串。
String不可变有什么好处
-
String常量池的必要条件。String常量池就是一个由JVM创建的特殊内存区域,用于存放字符串常量,当创建一个字符串时,JVM先去池中寻找是否存在,存在则返回,不存在则创建。即多个具有相同字符序列的字符串引用会指向池中同一个对象。如果有一个引用变量对其修改,那其他引用变量的值随之修改,缓存就无意义了。
-
因为不可变,所以是线程安全的。
-
很适合作为
HashMap
的Key。String的hashCode()
方法在第一次调用的时候会缓存它的hash值,再次调用的时候无需再次计算。关于这一点,我们去看它的源码:将hash函数的计算结果赋值给String的成员变量hash
,第二次计算就能直接返回。从这里可以看出,从HashMap
、HashSet
等使用hash函数计算元素位置的集合中查找一个元素是非常快的。
String
的hashCode()
方法:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) { // 只会判断一次,第二次直接 return h
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用