以下代码会生成多少个String对象?
String s1="Hello"; //"Hello" is in String Pool Object #1
String s2 = s1.substring(2,3);//String object #2
String s3 = s1.toString();
String s4 = new StringBuffer(s1).toString(); //String Object #3
这是我正在阅读的一本Java练习题的问题。 没有答案,所以我不确定我的答案是否正确。是否创建了3个或5个字符串对象? toString()是否创建了一个新的String对象?我在网上查了一下,发现toString()“返回对象的字符串表示”。我不太明白这意味着什么。
答案 0 :(得分:7)
它会创造三个。你的分析是正确的。
toString()是否创建了一个新的String对象?我在网上查了一下,发现toString()“返回对象的字符串表示”。
这是通用Object.toString
的描述,但String
会覆盖它以提供更具体的行为。它的版本以这种方式记录:
此对象(已经是字符串!)本身已返回。
[link]
答案 1 :(得分:4)
我认为你是对的。 String对象的数量为3 NOT 5。
s1.toString();
javadoc说:
此对象(已经是字符串!)本身已返回。
new StringBuffer(s1)
创建新的String对象。
答案 2 :(得分:3)
无论何时使用new关键字创建字符串对象,无论字符串池中是否已存在字符串,它都将创建一个新的String对象
String s1="Hello"; //this will create a new string object and add it to the pool of strings
String s2 = s1.substring(2,3);//String object #2 again creates a string and adds it in the pools of strings
String s3 = s1.toString();//this will not create a new object but simply refer to already existing object in the pool of strings
String s4 = new StringBuffer(s1).toString(); //String Object #3 this will create a new object as you are using new keyword
一个例子
public class Main {
public static void main(String[] args) {
String s1 = "abc";//created a string and added it to pool of string
String s2 = "abc";//no need to create a new object
String s3 = new String("abc");
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
System.out.println("s2 = " + s3);
System.out.println("s1 == s2? " + (s1 == s2));//proves that the ref refer to same object
System.out.println("s1 == s3?"+ (s1==s3));
System.out.println("s1.equals(s2)? " + (s1.equals(s2)));
}
}
输出
s1 = abc
s2 = abc
s3 = abc
s1 == s2? true
s1 == s3? false
s1.equals(s2)? true
答案 3 :(得分:0)
您的问题的答案取决于实施,并具有误导性。在代码片段的末尾可能有2到4个“字符串对象”,究竟有多少依赖于JVM,以及实习生的小字符串(如果有的话)的积极程度。正如已经指出的那样,JDK文档指定String.toString()返回对象,所以答案应该是“2或3”;但是,依靠这种行为你会非常愚蠢。
我说这是误导的原因是你从不关心“String对象的数量”。 Java中的对象非常轻,你从不担心计算它们。
我要添加的唯一资格是,虽然您从不关心对象计数,但您确实关心引用。在字符串的情况下,令人讨厌的惊喜可以是对底层字符数组的引用数。字符串对象是共享char数组的flyweights,忘记这一点会导致严重的内存泄漏。在java程序上耗尽堆的一种非常简单的方法是:
while(!multiGBFileEOF) {
String bigString = readMultiMBString();
int index = findSmallFeature(bigString);
String featureOfInterest = bigString.substring(index, index+4);
featureList.add(featureOfInterest);
}
featureList应该最多只有几个10KB(每个〜大约1000个列表项*(对于arrayref为4-8个字节,对于对象为12-20个字节,对于char数组为8-16个字节),即琐碎的但是因为一些常见的JVM实现共享由substring()生成的字符串的后备数组,所以最终可能会尝试将整个文件存储在内存中。解决方案是通过调用{{1}来强制显示底层数组的副本。这里你不关心String copy = new String(featureOfInterest)
和copy
是否是同一个对象,只要featureOfInterest
不对copy
后面的char数组进行别名。
祝你学习顺利。
答案 4 :(得分:0)
它将创建3个String对象。 String类的toString()方法实现打印内容;它不会创建任何新对象。