12.String Table
一、String的基本特性
String str="hello";
String str=new Stirng("hello");
String 被final 修饰,不可被继承,底层(1.8), char[] jdk9是byte[]+标识
放在字符串常量池(hash、数组+链表),在堆中1.8
二、String的内存分配
String str="hewllo" 放常量池中
data.intern() 将data字符串放常量池中
1.6 Stringtable 在 方法区(永久代)
1.7及以后 在堆区
Stringtable 为什么要移动到堆中在1.7->
三、String的基本操作
字符串常量池不能存放字符串相同的变量,和 hash存储有关
四、字符串拼接操作
1.常量与常量的拼接结果放在常量池,原理是 编译器优化
2.常量池不会存在相同内容的常量
3.只要有变量,结果就放在 堆(不是常量池)中,需要先new StringBuilder、append()、toString()该方法被重写过了。变量拼接的原理是StringBuilder
4.如果拼接的结果调用intern()方法,则主动将结果放在常量池中,并且返回对象地址,如果有,直接返回对象地址
5.final修饰的变量 是常量
4.1、第一种情况:
4.2、第三种情况:
4.3、另外情况
4.4、效率方面
五、intern()的使用
String data; data.intern();
如果字符串常量池中 没有data 字符串的话,则在常量池中生成,就将该new的地址放在常量池中,即 data=常量池找那个的地址
如果字符串常量池中 有data 字符串的话,并且,如果data是new 的,那data 就是在堆中的地址
如果让str去接收的话, str=data.intern().那么就会 str 就是常量池中的地址
5.1、情况一:
**String s1=new String("ab") 常量池中存在ab,s1是堆中的ab **
s1.intern(); 常量池有ab 那么这一行就没有起作用,如果 去接收它的返回值, 那么返回值就是 在常量池中的地址
5.2、情况二:
String s1=new String(a)+new String (b) 常量池有a,有b ,但是不存在ab
** s1.intern(); 常量池不存在ab的话,s1指向常量池中的地址,如果 去接收它的返回值,那么 返回值=s1,那么 s1和返回值 是同一个 常量池中的地址**
.....
如何保证字符串s在常量池中呢?
5.1、补充:思考题
5.2、补充:面试题
六、String Table的垃圾回收G1
七、G1中的String去重操作
重复是指 .equals=true
或者s1.intern()==s2.intern()
char[] 的去重