字符串实习在Java 7+中如何工作?

所以,我意识到我要提出的问题涉及到一次又一次被打死的话题,然而,即使在阅读了我能找到的所有答案和文档之后,我仍然对此感到困惑。字符串实习。 也许是因为我对JVM缺乏了解; 也许是因为Java 7中引入的变化使许多上述答案和文档贬值。 无论哪种方式,我都被卡住了,我希望有人可以帮助我更清楚地理解这个概念……

String a = "text"; String b = new String("text"); 

在上面的例子中,我理解将创建两个String对象。 我也明白在内存中只有一个包含序列’t’,’e’,’x’和’t’的char数组。 但是,在内存中实际存储的每个字符串对象是什么? 如果我读过的内容我已经正确阅读:变量a的引用将存储在常量池中,而b的引用将存储在堆中,对吧? 如果是这种情况,我对实习池如何维护实习字符串感到困惑。 它是否跟踪常量池中定义的字符串以及从堆中手动内化(调用.intern() )的字符串? JVM是否创建在常量池中定义的字符串对象并将它们加载到实习池中? 我很困惑这一切是如何运作的……

再次,对于提出这样令人困惑/愚蠢的问题感到遗憾,只是我对JVM的结构和内部工作相对较新,而且其中很多都让我头晕目眩。 谢谢!

当你声明时,java中有一个名为String Memory Pool的东西:

 String str1="abc"; 

它转到那个内存池而不是堆上。 但是当你写:

 String str2=new String("abc"); 

它在堆上创建一个完整的成熟对象,如果你再次写:

 String str3 = "abc"; 

它不会在池上创建任何更多的对象,如果该文字已经存在,它将检查池,它将分配给它。 但写作:

 String str4 = new String("abc"); 

将再次在堆上创建一个新对象

关键是:

在写入时,将始终在堆上创建一个新对象:

 new String("abc"); 

但是如果你在不使用关键字new的情况下直接分配字符串,它将只从内存池中引用(或者如果内存池中不存在则创建)

intern()方法查找字符串是否存在于内存池中,如果不存在,则将其添加到内存池并返回对它的引用。 所以在使用这个方法之后你的String引用没有指向堆上的任何对象,它指向String Memory Pool中的一个对象(另外,请注意内存池只包含唯一的字符串)

当你说new String()你会得到一个新的Object引用

 String a = "text"; String b = new String("text"); System.out.println(a == b); b = b.intern(); System.out.println(a == b); 

然后首先a == b将显示false因为它们是不同的引用。 如果我们通过说b = b.intern()我们intern() b然后我们可以再次测试并获得true 。 我希望有所帮助。 自1.0版以来,上述代码在Java中的工作方式相同(现在它仍然在Java 8中以这种方式工作)。