https://www.processon.com/view/link/5eb50263e401fd16f42345f4

一、常量比较

1.常量池

  1. @Test
  2. public void test1() {
  3. String test1 = "abcd";
  4. String test2 = "abcd";
  5. System.out.println(test1 == test2);
  6. System.out.println(test1.equals(test2));
  7. }
  8. true
  9. true
  10. 解析:当常量池中不存在时,创建新字符串,存在时,test1test2都指向常量池中同一位置。
  11. @Test
  12. public void test2() {
  13. String test1 = "a"+"b"+"c"+"d";
  14. String test2 = "abcd";
  15. System.out.println(test1 == test2);
  16. System.out.println(test1.equals(test2));
  17. }
  18. true
  19. true
  20. 解析:编译器【进行优化】。在编译阶段,a,b,c,d会优化成abcd字符串,在类加载阶段把abcd字符串纳入运行时常量池中。

常量池相关 - 图1

2.堆中分配与常量池比较

  1. @Test
  2. public void test3() {
  3. String test1 = "abcd";
  4. String test2 = new String("abcd");
  5. System.out.println(test1 == test2);
  6. System.out.println(test1.equals(test2));
  7. }
  8. false
  9. true
  10. 解析:
  11. ==比较内存地址,内存地址不同。
  12. equals比较内容。

常量池相关 - 图2

3.堆中分配比较

  1. @Test
  2. public void test4() {
  3. String test1 = new String("abcd");
  4. String test2 = new String("abcd");
  5. System.out.println(test1 == test2);
  6. System.out.println(test1.equals(test2));
  7. }
  8. false
  9. true
  10. 解析:
  11. ==比较内存地址,内存地址不同。
  12. equals比较内容。

常量池相关 - 图3

4.字符串占据常量池与堆

  1. @Test
  2. public void test4() {
  3. String test1 = "ab" + new String("cd");
  4. String test2 = new String("abcd");
  5. System.out.println(test1 == test2);
  6. System.out.println(test1.equals(test2));
  7. }
  8. false
  9. true
  10. 解析:
  11. ==比较内存地址,内存地址不同。
  12. equals比较内容。

常量池相关 - 图4

5.intern方法引入

  1. @Test
  2. public void test5() {
  3. String test1 = "ab" + new String("cd");
  4. String test2 = "abcd";
  5. String test3 = test1.intern();
  6. System.out.println(test1 == test3);
  7. System.out.println(test2 == test3);
  8. System.out.println(test1.equals(test2));
  9. }
  10. false
  11. true
  12. true
  13. 解析:
  14. ==比较内存地址,内存地址不同。
  15. equals比较内容。
  16. intern方法,将一个字符串尝试放入运行时常量池中。若常量池中没有则直接添加常量池中;若存在,则返回常量池中该字符串的引用。

常量池相关 - 图5