我被问到这个问题:
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对象中只有两个不会丢失。
这是对的吗?
答案 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
对象的方法。
在这种情况下,JVM搜索字符串池以查看是否已存在等效字符串。如果是,则返回对该引用的引用。如果没有,将其添加到字符串池并返回引用。 因此可能会创建一个新对象,也可能不会。
现在,JVM必须在堆上创建一个对象。由于新。如果字符串池中已存在OneString
,则无关紧要。
您还可以将字符串放入池:
您可以在String对象上调用intern()。这将把String对象放在池中(如果它尚不存在),并返回对池化字符串的引用。 (如果它已经在池中,它只返回对已存在的对象的引用)。
您可以查看以下链接:
What is the Java string pool and how is "s" different from new String("s")?
答案 1 :(得分:1)
看起来正确。这是一个SCJP考试问题btw。
concat返回一个新的String,这个丢失了。 第一个s1被“春冬”覆盖了
关于Java中的字符串应该了解的两件事:
干杯 基督教
答案 2 :(得分:1)
java中的字符串是不可变的。有分配的字符数组,以及一些周围的信息,如偏移和长度。如果您使用字符串文字初始化字符串,编译器会尝试优化并为每个文字只创建一个字符串对象 - 这是可能的,因为它们是不可变的。
如果你对字符串进行连接或+,那么新的字符串将被解析并且数据被合并在一起(性能损失。
与此相反,从字符串中创建子字符串几乎是免费的 - 不会复制任何数据