0

下面的代码会产生多少个 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() “返回对象的字符串表示形式”。我不太明白这是什么意思。

4

5 回答 5

7

它将创建三个。你的分析是正确的。

toString() 会创建一个新的 String 对象吗?我在网上查了一下,发现 toString() “返回对象的字符串表示形式”。

这是 generic 的描述Object.toString,但String会覆盖它以提供更具体的行为。它的版本是这样记录的:

这个对象(它已经是一个字符串!)本身被返回。

[链接]

于 2012-11-09T04:43:05.217 回答
4

我认为你是对的。String 对象的数量将是 3 而不是 5。

s1.toString();javadoc 说:

这个对象(它已经是一个字符串!)本身被返回。

new StringBuffer(s1)

创建新的字符串对象。

于 2012-11-09T04:42:41.950 回答
3

Whenever you use a new keyword to create a string object it will create a new String object no matter the string is already present in the pool of strings

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 

an example

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)));    
  }
}

the output

s1 = abc
s2 = abc
s3 = abc
s1 == s2? true
s1 == s3? false
s1.equals(s2)? true
于 2012-11-09T04:52:07.397 回答
0

您的问题的答案取决于实现,并且具有误导性。在代码片段的末尾可能有 2 到 4 个“字符串对象”,具体有多少取决于 JVM,以及它对小字符串的执行程度(如果有的话)。正如已经指出的 JDK 文档指定 String.toString() 返回对象,所以答案应该是“2 或 3”;但是,依赖这种行为是非常愚蠢的。

我说这具有误导性的原因是您从不关心“字符串对象的数量”。Java 中的对象重量非常轻,您从不担心计算它们。

我要补充的唯一条件是,虽然您从不关心对象计数,但您确实关心引用。在字符串的情况下,一个令人讨厌的惊喜可能是对底层 char 数组的引用数量。字符串对象是共享 char 数组的享元,忘记这一点会导致严重的内存泄漏。用尽 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() 生成的字符串的后备数组,这最终可能会尝试将整个文件存储在内存中。解决方案是通过调用来强制底层数组的显式副本String copy = new String(featureOfInterest)。这里你不关心ifcopyfeatureOfInterest是否是同一个对象,只要copy不给 char 后面的数组起别名bigString

祝你学习顺利。

于 2012-11-09T05:28:19.847 回答
0

它将创建 3 个 String 对象。String 类的 toString() 方法实现打印内容;它不会创建任何新对象。

于 2012-11-09T05:39:04.030 回答