packagecom.erick.string.d01;importorg.junit.Test;publicclassDemo01{@Testpublicvoidmethod01(){String first ="erick";String second ="erick";/*字符串常量池中,不会保存同样的字符
* 字符底层,是用byte[]填充数据的,数组不会扩容,只会再生成一个新的*/System.out.println(first == second);// 指向同一个引用地址
second ="hehe";System.out.println(first == second);// 引用地址已经变化}@Testpublicvoidmethod02(){String first ="Erick";String second ="Erick";
second +="nihao";System.out.println(first==second);// 已经重新分配了一个新的数组}@Testpublicvoidmethod03(){String first ="Erick";String second = first.replace("E","a");// 上面其实是生成了一个新的byte[]来存储字符串System.out.println(first==second);}}
/*前端编译期间优化
* 1. 会直接将first写成 "abc",存储在常量池中
* 2. 将second的引用地址指向常量池的 "abc"*/@Testpublicvoidtest01(){String first ="a"+"b"+"c";String second ="abc";System.out.println(first == second);// trueSystem.out.println(first.equals(second));// true}
对应字节码的反编译文件来查看
//// Source code recreated from a .class file by IntelliJ IDEA// (powered by FernFlower decompiler)//packagecom.erick.string.d01;importorg.junit.Test;publicclassDemo02{publicDemo02(){}@Testpublicvoidtest01(){String first ="abc";String second ="abc";System.out.println(first == second);System.out.println(first.equals(second));}}
方式1: String s ="erick"; // 字面量定义的方式
方式2: String s = new String("erick").intern();
String s = new StringBuilder("erick").toString().intern();
- 就是为了保证常量池中的字符串不会重复,这样就保证了查询时候的性能