Java如何处理内存中的String对象?

时间:2012-01-25 06:26:46

标签: java string scjp

我被问到这个问题:

String s = "abc"; // creates one String object and one
          // reference variable
In this simple case, "abc" will go in the pool and s will refer to it.
String s = new String("abc"); // creates two objects,
                 // and one reference variable*

基于以上细节,在下面代码的println语句之前创建了多少个String对象和多少个引用变量?

String s1 = "spring ";
String s2 = s1 + "summer ";
s1.concat("fall ");
s2.concat(s1);
s1 += "winter ";
System.out.println(s1 + " " + s2);

我的回答是 这段代码片段的结果是春夏春夏

有两个参考变量,s1和s2。总共有八个String对象 创建如下:“春天”,“夏天”(迷失),“春夏”,“秋天”(迷失),“春天 秋天“(迷失),”春夏“(迷失),”冬天“(迷失),”春天的冬天“(此时”春天“失去了)。

在此过程中,八个String对象中只有两个不会丢失。

这是对的吗?

3 个答案:

答案 0 :(得分:4)

答案是:2个引用和8个对象。

String s1 = "spring "; //One reference and 1 object in string pool. (if it didn't exist already)

String s2 = s1 + "summer "; //Two references and 3 objects

s1.concat("fall "); //Two references and 5 objects

s2.concat(s1); //Two references and 6 objects

s1 += "winter "; //Two references and 8 objects

System.out.println(s1 + " " + s2);

现在你的问题: Java如何处理内存中的String对象?

Java提供了两种创建类String对象的方法。

  1. String str1 =“OneString”;
  2. 在这种情况下,JVM搜索字符串池以查看是否已存在等效字符串。如果是,则返回对该引用的引用。如果没有,将其添加到字符串池并返回引用。 因此可能会创建一个新对象,也可能不会。

    1. String str1 = new String(“OneString”);
    2. 现在,JVM必须在堆上创建一个对象。由于。如果字符串池中已存在OneString,则无关紧要。

      您还可以将字符串放入池:

        

      您可以在String对象上调用intern()。这将把String对象放在池中(如果它尚不存在),并返回对池化字符串的引用。 (如果它已经在池中,它只返回对已存在的对象的引用)。

      您可以查看以下链接:

      What is the Java string pool and how is "s" different from new String("s")?

      Questions about Java's String pool

答案 1 :(得分:1)

看起来正确。这是一个SCJP考试问题btw。

concat返回一个新的String,这个丢失了。 第一个s1被“春冬”覆盖了

关于Java中的字符串应该了解的两件事:

干杯 基督教

答案 2 :(得分:1)

java中的字符串是不可变的。有分配的字符数组,以及一些周围的信息,如偏移和长度。如果您使用字符串文字初始化字符串,编译器会尝试优化并为每个文字只创建一个字符串对象 - 这是可能的,因为它们是不可变的。

如果你对字符串进行连接或+,那么新的字符串将被解析并且数据被合并在一起(性能损失。

与此相反,从字符串中创建子字符串几乎是免费的 - 不会复制任何数据