对象的堆与字符串常量池内存表示

Heap vs String Constant Pool memory representation for Object

在 Java 7 或更低版本中,如果使用以下语法创建字符串

String s1=new String("abc");

根据this link,每当我们创建一个字符串对象时,都会创建两个对象,一个在堆区,一个在字符串常量池,字符串对象引用总是指向堆区对象如下所示。

----------------------------------------------
|        Heap         | String Constant Pool |
|---------------------|-----------------------                      
|                     |                      |
|      "abc"          |       "abc"          |
|        ^            |                      |
|        |            |                      |
|       s1            |                      |

如果我们创建另一个具有与

相同值的 String 对象,内存表示将是什么
String s2=new String("abc");

这会在堆中创建另一个具有相同值的对象吗?
或者它只会将引用 String 常量池的对象创建到堆中?

----------------------------------------------
|        Heap         | String Constant Pool |
|---------------------|-----------------------                      
|                     |                      |
|    "abc"  "abc"     |       "abc"          |
|      ^      ^       |                      |
|      |      |       |                      |
|     s1     s2       |                      |

正如 Andy Turner 所说,new 运算符总是生成一个新实例。由JLS保证。

唯一的小问题是在某些情况下(例如,如果在某些 JVM 版本中启用了逃逸分析),new 运算符可能会在堆栈而不是堆上分配对象。