1、jdk1.8之后没有永久代,字符串常量池在堆中,运行时常量池在元空间
2、String str = “test”;
先判断test在字符串常量池值是否存在,如果存在就直接返回引用,不存在,会在字符串常量池中创建一个test,返回引用
3、String str = new String(“test”);
在字符串常量池和堆中都创建一个test,他也会先判断在字符串常量池中是否存在test,不存在就创建,然后再去堆里面创建一个引用返回该引用
4、intern
(1)字符串常量池中存在test
String str = new String("test");
String str1 = str.intern();
//false
System.out.println(str=str1);
调用intern()方法时,因为是str是new出来的,所以他会返回字符串常量池中的引用
(2)字符串常量池中不存在test
String str = new String('te')+new String("st");
String str1 = str.intern();
/**
* jdk7以及之后返回 true
* jdk7以前返回false
*/
System.out.println(str==str1);
如下如图
在jdk7以及之后的版本,调用intern()方法会在常量池中创建一个指向堆中该字符串的引用。
jdk7之前他会在字符串常量池中也创建一个test,返回该引用
5、字符串相加
String str = "t";
String str1 = "e";
String str2 = "s";
String str3 = "t";
String test = "test";
String s = str + str1 + str2 + str3;
//false
System.out.println(test ==s);
对于字符串相加,他在底层的逻辑相于用StringBuilder来append
StringBuilder stringBuilder = new StringBuilder();
String toString = stringBuilder.append(str).append(str1).append(str2).append(str3).toString();
如下字节码
Integer
Integer a = 127;
Integer b = Integer.valueOf(127);
//true
System.out.println(a == b);
Integer a = 128;
Integer b = Integer.valueOf(128);
//false
System.out.println(a == b);
Integer a = 127; 在底层就会调用Integer.valueOf(),如下图
并且缓存池的范围是在-128~127之间