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

