定义
String
String是一种不可变的字符串类型。
intern()
- 若字符串常量池中不存在该字符串,则:
- Java6(JDK6)及之前:复制一份字符串到永久代中的字符串常量池中,并返回该字符串的引用
- Java7(JDK7)及之后:复制当前字符串到堆中的字符串常量池中,并返回该字符串的引用
- 若字符串常量池中存在该字符串,则返回该字符串的引用
字符串常量池
字符串常量池用于缓存字符串对象,里面保存了字符串对象的引用。
使用字符串字面量创建字符串时:
String s = "abc";JVM先在字符串常量池中查找是否存在"abc":
- 若存在,则直接返回该字符串的引用
- 若不存在,则在字符串常量池中创建字符串
"abc",然后返回该字符串的引用
问题
String为什么设计为不可变
- 安全性:Java中类名、文件路径、URL、数据库连接信息等都用String来表示,如果String是可变的,这些字符串在被系统检查后可能会被修改,这样就会产生安全漏洞。
- 线程安全:不可变对象天然就是线程安全的,可以在不同的线程间进行传递,同时进行读取。
- 字符串常量池:字符串常量池依赖于String的不可变性,如果String是可变的,在一处对字符串进行修改,其他引用也会被修改,字符串常量池就失效了。
- 哈希集合:String常常用来作为哈希集合的Key,如果String可变,String的hashCode计算结果就不能被缓存,原有hashCode对应的值也会无法找到,造成数据丢失和内存泄露。
new String()创建的对象数量
String s = new String("abc");这行代码可能创建1~2个对象:
- 若字符串字面量
"abc"不存在于字符串常量池中,将在字符串常量池中创建一个String对象。 - 在堆上创建一个内容为
"abc"的新的String对象。