Java字符串池 - 字符串在堆上的存储方式

时间:2017-01-05 13:20:46

标签: java

让我们考虑下面的代码:

String s1 = "Hello world"
String s2 = "Hello world XXX"

我猜,这些字符串在Java String Pool中存储了两个字符串:

  • Hello world
  • Hello world XXX

这些字符串是如何存储在堆上的String Pool的内存中的?是否存储在字符串池的特殊堆中? SP是否存在任何字符串索引,或者这些字符串是否存储在有序集合中?如果" Hello world AAA"加入SP?感谢。

2 个答案:

答案 0 :(得分:0)

字符串是不可变的。对于您的示例,String Pool中将有2个对象。如果您想知道如何创建,这里有一个非常好的帖子,简单的解释:http://www.journaldev.com/797/what-is-java-string-pool

如果您将使用:

String s1 = "Hello World";
String s2 = "Hello World";
String s3 = "Hello WorldXXX";

然后将有2个对象,一个用于Hello World,因此s1 == s2;为真(同一个对象),但Hello WorldXXX将是内存中的另一个对象。

在内存中存储字符串由字符串实习定义,这里是wiki上的解除。

对于您的评论:如果您调用operator new ,则取决于它,因为它在堆空间中创建(在String Pool之外)。如果你在我的例子中使用它,那么它们存储在String Pool中,在那里决定,如果它已经存在于String池中,那么它们就像对象一样(String Pool中的内存相同)。

同时尝试检查https://en.wikipedia.org/wiki/Flyweight_pattern;)

答案 1 :(得分:0)

当Java虚拟机在编译期间为实体分配空间时(例如您的示例),应该区分发生的情况:

String s1 = "Hello world";
String s2 = "Hello world XXX";

并且在运行时分配字符串空间时:

String s3 = new String("Hello world");
String s4  = new String("Hello world XXX");

在第一种情况下,JVM构造堆中内存中的所有字符串。将每个新出现的事件与现有条目进行比较,如果两个值相同,则它们指向内存空间中的相同地址(换句话说条件:s1 == s2true)。这是可能的,因为Java中的String是不可变的,因此其哈希码在创建时被缓存,并且不需要再次计算。

在第二种情况下,使用new运算符强制,JVM在内存模型中分配新空间。这意味着,条件s1 == s3false。这就是为什么建议使用字符串比较方法:String.equals(),因为它涉及变量值,而不是内存地址。

相关问题