一、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及以后 在堆区


12.String Table_常量池

Stringtable 为什么要移动到堆中在1.7->

12.String Table_常量池_02

三、String的基本操作
    字符串常量池不能存放字符串相同的变量,和 hash存储有关


四、字符串拼接操作
    1.常量与常量的拼接结果放在常量池,原理是 编译器优化
2.常量池不会存在相同内容的常量
3.只要有变量,结果就放在 堆(不是常量池)中,需要先new StringBuilder、append()、toString()该方法被重写过了。变量拼接的原理是StringBuilder
4.如果拼接的结果调用intern()方法,则主动将结果放在常量池中,并且返回对象地址,如果有,直接返回对象地址
5.final修饰的变量 是常量


第一种情况:

12.String Table_字符串拼接_03

第三种情况:

12.String Table_编译器优化_04

另外情况

12.String Table_字符串常量池_05

效率方面

12.String Table_编译器优化_06

五、intern()的使用
    String data; data.intern();
如果字符串常量池中 没有data 字符串的话,则在常量池中生成,就将该new的地址放在常量池中,即 data=常量池找那个的地址
如果字符串常量池中 有data 字符串的话,并且,如果data是new 的,那data 就是在堆中的地址
如果让str去接收的话, str=data.intern().那么就会 str 就是常量池中的地址


情况一:

**String s1=new String("ab") 常量池中存在ab,s1是堆中的ab **

s1.intern(); 常量池有ab 那么这一行就没有起作用,如果 去接收它的返回值, 那么返回值就是 在常量池中的地址

情况二:

String s1=new String(a)+new String (b) 常量池有a,有b ,但是不存在ab

** s1.intern(); 常量池不存在ab的话,s1指向常量池中的地址,如果 去接收它的返回值,那么 返回值=s1,那么 s1和返回值 是同一个 常量池中的地址**

.....

12.String Table_编译器优化_07

如何保证字符串s在常量池中呢?

12.String Table_编译器优化_08

补充:思考题

12.String Table_常量池_09

补充:面试题

12.String Table_字符串拼接_10

六、String Table的垃圾回收G1七、G1中的String去重操作
    重复是指 .equals=true
或者s1.intern()==s2.intern()
char[] 的去重


12.String Table_字符串拼接_11