https://www.processon.com/view/link/5eb50263e401fd16f42345f4
一、常量比较
1.常量池
@Test
public void test1() {
String test1 = "abcd";
String test2 = "abcd";
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
}
true
true
解析:当常量池中不存在时,创建新字符串,存在时,test1、test2都指向常量池中同一位置。
@Test
public void test2() {
String test1 = "a"+"b"+"c"+"d";
String test2 = "abcd";
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
}
true
true
解析:编译器【进行优化】。在编译阶段,a,b,c,d会优化成abcd字符串,在类加载阶段把abcd字符串纳入运行时常量池中。
2.堆中分配与常量池比较
@Test
public void test3() {
String test1 = "abcd";
String test2 = new String("abcd");
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
}
false
true
解析:
==比较内存地址,内存地址不同。
equals比较内容。
3.堆中分配比较
@Test
public void test4() {
String test1 = new String("abcd");
String test2 = new String("abcd");
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
}
false
true
解析:
==比较内存地址,内存地址不同。
equals比较内容。
4.字符串占据常量池与堆
@Test
public void test4() {
String test1 = "ab" + new String("cd");
String test2 = new String("abcd");
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
}
false
true
解析:
==比较内存地址,内存地址不同。
equals比较内容。
5.intern方法引入
@Test
public void test5() {
String test1 = "ab" + new String("cd");
String test2 = "abcd";
String test3 = test1.intern();
System.out.println(test1 == test3);
System.out.println(test2 == test3);
System.out.println(test1.equals(test2));
}
false
true
true
解析:
==比较内存地址,内存地址不同。
equals比较内容。
intern方法,将一个字符串尝试放入运行时常量池中。若常量池中没有则直接添加常量池中;若存在,则返回常量池中该字符串的引用。