今天做了一道练习题,题目如下:public String makinStrings() { 
(1) String s = "Fred"; 
(2) s = s + "47"; 
(3) s = s.substring(2, 5); 
(4) s = s.toUpperCase(); 
(5) return s.toString(); 
} How many String objects will be created when this method is invoked? 给出的标准答案是:3个第(1)、(2)肯定会有两个,那么第3个是(3)(4)(5)中的哪一行创建的?String对象不是改变的时候都会new一个对象吗?请教大虾

解决方案 »

  1.   

      s = s.substring(2, 5); 这里变大写是不会new的,但是截去相对于新建了
      

  2.   

     String s="xxx" ;s 只是引用变量,当String s=new String("xxx"); 这创建了两个对象,一个s,一个字符串"xxx";
     所以题目的肯定有两个对象“Fred" "Fred47" .
     toUpperCase() 方法将所以字符串 都大写,因此又创建了一个都是大写的字符串对象”FRED47"
      

  3.   

    这个答案,不是很清楚到底对不对呀,
    个人感觉3,4应该是会产生新对象的
    我们看String的source code,
    substring(int,int)方法如下,我们可以看到索引合理的话,肯定会new一个String返回的,所以会产生一个对象    public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
        }再看toUpperCase方法的源代码,我们可以看到,在方法最后要返回的时候也是肯定会new 一个对象的    public String toUpperCase() {
            return toUpperCase(Locale.getDefault());
        }
        public String toUpperCase(Locale locale) {
    if (locale == null) {
        throw new NullPointerException();
            }
            ........
            return new String(0, result.length, result);
        }
    所以说这两个方法都会生成新的String对象再看String的toString方法,如下,它只是返回它本身,不会生成新的对象    public String toString() {
    return this;
        }
      

  4.   

    tavor解析得很详细,可能答案真的错了
      

  5.   

    (3)    s = s.substring(2, 5); 这里截取创建了一个
      

  6.   

     哦,对不起,没有看到方法substring(2, 5); 方法返回ed4,这里创建了一个对象,大写toUpperCase()不会创建对象?我不知道,高手指点啊,为何字符串变成大写就没有创建对象??
      

  7.   

    toUpperCase的源码我这和tavor 不一样莫非不是一个版本的jdk,我这return的是this   public String toUpperCase(Locale locale) {
    if (locale == null) {
        throw new NullPointerException();
            }        int     firstLower; /* Now check if there are any characters that need to be changed. */
    scan: {
        for (firstLower = 0 ; firstLower < count; ) {
    int c = (int)value[offset+firstLower];
    int srcCount;
    if ((c >= Character.MIN_HIGH_SURROGATE) &&
        (c <= Character.MAX_HIGH_SURROGATE)) {
        c = codePointAt(firstLower);
        srcCount = Character.charCount(c);
    } else {
        srcCount = 1;
    }
    int upperCaseChar = Character.toUpperCaseEx(c);
    if ((upperCaseChar == Character.ERROR) ||
        (c != upperCaseChar)) {
        break scan;
    }
    firstLower += srcCount;
        }
        return this;
    }
      

  8.   

    不好意思方法太长最后返回的是        return new String(0, count+resultOffset, result);
      

  9.   

    (1)    String s = "Fred"; 
    (2)    s = s + "47"; 我认为(1)(2)就已经有3个对象了
      

  10.   

    1,2,3
    substring
    public String substring(int beginIndex,
                            int endIndex)返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,一直到索引 endIndex - 1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。 
      

  11.   

    toUpperCase
    public String toUpperCase()使用默认语言环境的规则将此 String 中的所有字符都转换为大写。此方法等效于toUpperCase(Locale.getDefault())。 
      

  12.   

    答案是正确的,第一句的String s = "Fred";"Fred"是在String Pool中,有String类维护,
    可重复使用。举个例子:
    第一种情况:
    String s = “aaa”;
    String ss = “aaa”;
    第二种情况:
    String s = new String("aaa");
    String ss = new String("aaa");第一种情况:其实s和ss引用的是同一个地址,故s == ss的结果是true
    第二种情况:s和ss引用的不同的地址(但内容相同,都为“aaa”),故s==ss的结果是false所答案是对的,就是三个
      

  13.   

    我没有说S不是引用啊!!string池里 
    (1)    String s = "Fred"; //先有"Fred"第一个对象。2)    s = s + "47"; //"47"第二个对象,,"Fred47"第三个对象。