java中对于字符串,有两种存储方式:1.字符串对象存储在常量池中(stringtable);2.字符串存储在堆内存中。
一.常量池
字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能。JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化为字符串开辟一个字符串常量池,类似于缓存区创建字符串常量时,首先查询字符串常量池是否存在该字符串存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中。
二.字符串的三种操作
1.直接赋值
//这种方法创建字符串对象,jvm会去常量池中创建a对象,然后返回a的引用
String str1 = "a";
2.New 一个字符串对象
//这种方式创建字符串对象,会保证常量池和堆内存中都有这个对象,先检查常量池中是否存在对象a,没有则创建,然后再去内存中创建字符串对象a,返回内存引用
String str2 = New String("a");
3.intern方法
//当调用intern方法时,查询常量池是存在等于此字符串的对象,有则返回对应的引用,没有则在常量池中创建字符串对象,然后返回引用
String str3 = str2.intern();
三.示例代码
四. 字符串常量池位置
Jdk1.6及之前:有永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池。
Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里。
Jdk1.8及之后:无永久代,运行时常量池在元空间,字符串常量池里依然在堆里。