演进
Java6
- char[]、offset、count、hash 四个成员变量。
- offset、count 使得String.subString方法可以共享char[]数组,但是存在内存泄漏问题。
思考:
1 | JDK1.6 |
Java7、8
- char[]、hash 2个成员变量
- String.substring 方法也不再共享 char[]。
Java9
- byte[]、coder、hash 三个成员变量
- 改用byte[] 为了节约空间,coder 标识编码方式(0:只包含Latin-1、1:包含UTF-16)
创建&内存位置
2中创建方式:字面量(“abc”)、对象(new String()) ,存储位置有所不同。
- 字面量创建方式:如果
字符串常量池
存在直接返回、否则在常量池创建然后返回。 - 构造方法创建:先在字符串常量池寻找,找到后直接使用,未找到在对象中创建。
字符串常量池
内存位置:方法区-运行时常量池(jdk1.6)、堆-运行时常量池(jdk.7)、堆-元空间(jdk1.8),目前还存在堆内元空间。
特点
- 共享的:多个对象共用一个真实数据;
- 不可变:因为一旦变了所有的都会改变;
- 拼接字符串的性能较差的原因,每次都有创建新的;
比较
”“ 当且仅当确定两个对象都在常量池时 可以使用”“进行比较。任何时候都可以使用equals方法进行比较。
intern方法
返回字符串的常量池引用,不存在的话先将对象的字符串引用
放入常量池。强制共享对象,使用好了可以降低内存占用。
思考下面代码、为什么?
1 | String str1=new String("c")+new String("d"); |
编译优化
字符串拼接优化(+),编译后实际使用StringBuilder操作。
1 | String str3=new String("c")+new String("d"); |