System.out.println("a".toLowerCase() + "b" == "ab"); // false
请问各朋友,上面的"a".toLowerCase() + "b"的处理过程是怎么样的?

解决方案 »

  1.   

    先把"a"进行小写处理,然后和"b"连接在一起组成"ab"有啥看不懂的,典型的从左向右处理
      

  2.   

    "a".toLowerCase() + "b"    这个块使用的内存位置在 对空间中
    "ab"  这块是在栈空间中   
    ==比较的是两个对象的内存地址是否一致
    所以结果为false
      

  3.   

    System.out.println(("a".toLowerCase() + "b").equals("ab"));
      

  4.   

    LZ问的是toLowerCase的过程,看了下源码,没耐心看下去,给你贴一下,自己看吧
     public String toLowerCase(Locale locale) {
    if (locale == null) {
        throw new NullPointerException();
            }        int     firstUpper; /* Now check if there are any characters that need to be changed. */
    scan: {
        for (firstUpper = 0 ; firstUpper < count; ) {
    char c = value[offset+firstUpper];
    if ((c >= Character.MIN_HIGH_SURROGATE) &&
        (c <= Character.MAX_HIGH_SURROGATE)) {
        int supplChar = codePointAt(firstUpper);
        if (supplChar != Character.toLowerCase(supplChar)) {
            break scan;
        }
        firstUpper += Character.charCount(supplChar);
    } else {
        if (c != Character.toLowerCase(c)) {
            break scan;
        }
        firstUpper++;
    }
        }
        return this;
    }        char[]  result = new char[count];
    int     resultOffset = 0;  /* result may grow, so i+resultOffset
        * is the write location in result */        /* Just copy the first few lowerCase characters. */
            System.arraycopy(value, offset, result, 0, firstUpper); String lang = locale.getLanguage();
    boolean localeDependent =
                (lang == "tr" || lang == "az" || lang == "lt");
            char[] lowerCharArray;
            int lowerChar;
            int srcChar;
            int srcCount;
            for (int i = firstUpper; i < count; i += srcCount) {
        srcChar = (int)value[offset+i];
        if ((char)srcChar >= Character.MIN_HIGH_SURROGATE &&
            (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
    srcChar = codePointAt(i);
    srcCount = Character.charCount(srcChar);
        } else {
            srcCount = 1;
        }
                if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
                    lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
                } else {
                    lowerChar = Character.toLowerCase(srcChar);
                }
                if ((lowerChar == Character.ERROR) ||
                    (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
                    if (lowerChar == Character.ERROR) {
                        lowerCharArray =
                            ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
                    } else if (srcCount == 2) {
        resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
        continue;
                    } else {
        lowerCharArray = Character.toChars(lowerChar);
    }                /* Grow result if needed */
                    int mapLen = lowerCharArray.length;
    if (mapLen > srcCount) {
                        char[] result2 = new char[result.length + mapLen - srcCount];
                        System.arraycopy(result, 0, result2, 0,
                            i + resultOffset);
                        result = result2;
    }
                    for (int x=0; x<mapLen; ++x) {
                        result[i+resultOffset+x] = lowerCharArray[x];
                    }
                    resultOffset += (mapLen - srcCount);
                } else {
                    result[i+resultOffset] = (char)lowerChar;
                }
            }
            return new String(0, count+resultOffset, result);
        }
      

  5.   


    //反编译:
    System.out.println((new StringBuilder()).append("a".toLowerCase()).append("b").toString() == "ab");字节码:
       0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       3: new #3; //class java/lang/StringBuilder
       6: dup
       7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
       10: ldc #5; //String a
       12: invokevirtual #6; //Method java/lang/String.toLowerCase:()Ljava/lang/String;
       15: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       18: ldc #8; //String b
       20: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       23: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       26: ldc #10; //String ab
       28: if_acmpne 35
       31: iconst_1
       32: goto 36
       35: iconst_0
       36: invokevirtual #11; //Method java/io/PrintStream.println:(Z)V
       39: return
      

  6.   


    System.out.println("a".toLowerCase() + "b" == "ab"); // false
    System.out.println("ab".toLowerCase() == "ab"); // true
    System.out.println("AB".toLowerCase() == "ab"); // false为什么结果会这样? 2楼的朋友说得好像有点道理, 不过还是不明白, 不知哪位能否清楚的介绍下?
      

  7.   

    PS: 这是一道IBM的笔试题, 1楼的朋友不要小看了......
      

  8.   

    看了一下4楼贴出的源代码scan: {
            for (firstUpper = 0 ; firstUpper < count; ) {
            char c = value[offset+firstUpper];
            if ((c >= Character.MIN_HIGH_SURROGATE) &&
                (c <= Character.MAX_HIGH_SURROGATE)) {
                int supplChar = codePointAt(firstUpper);
                if (supplChar != Character.toLowerCase(supplChar)) {
                    break scan;
                }
                firstUpper += Character.charCount(supplChar);
            } else {
                if (c != Character.toLowerCase(c)) {
                    break scan;
                }
                firstUpper++;
            }
            }
            return this;
        }这一段是判断字符串是否需要转换,
    如果不需要的话就返回自身。
    因此这一句
    System.out.println("ab".toLowerCase() == "ab"); // true
    相当于System.out.println("ab" == "ab"); 在方法的最后一部分里面有这么一段        return new String(0, count+resultOffset, result);即最后如果字符串里面有字符都转换为小写,则返回一个新的字符串,
    这个字符串是new出来的,放在堆内存里面
    后面用着个字符串来进行连接时,新生成的字符串也是放在堆内存里边的
    System.out.println("a".toLowerCase() + "b" == "ab"); // false
    System.out.println("AB".toLowerCase() == "ab"); // false
    这时候你拿堆内存的字符串和常量池的字符串比较结果当然是false
      

  9.   


    楼上的大侠讲的似乎有些道理,可我的问题是"a".toLowerCase()不也是没有转换小写吗。。应该是返回本身啊难道你是说当a+b变成"ab"的时候,实际上对内存里new了一个String对象?
      

  10.   

    没错,再看:
    [code]
    System.out.println("a" + "b" == "ab"); // true
    [code]
      

  11.   

    字符串最最让人迷惑的问题,如:String str="a"+"b"+"c";问创建了几个对象?
    以及楼上各位所说的问题,能不能有谁能够把这些说明白点
      

  12.   

    String str="a"+"b"+"c";问创建了几个对象?这个问题真的很无聊...
    如果想让两个字符串的地址相等就用String 类的 intern()  方法,返回一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。
      

  13.   

    按照10楼java1109兄的说法,连接字符串操作是新建了一个字符串了。验证中……
      

  14.   

    反正比对象地址用==,比值就用equals就对了...
      

  15.   


    "ab" 应该是在Data Segment吧?
      

  16.   


    这时候,"a".toLowerCase() 和 "a" 比较是用“==”,而不是equals()方法,故比较的是地址,就是比较new出来的,就像  String s1 = new String("china");
                   String s2 = new String("china");
                   System.out.println(s1 == s2); 的时候,结果是false
     而 equals()方法是String类从其父类Object类中继承并重写了,这可以查API文档,equals方法比较的是字符串的序列,可明白?
      

  17.   


    //太好玩了,呵呵
    System.out.println("a".toLowerCase() + "b" == "ab"); // false
    System.out.println("ab".toLowerCase() == "ab"); // true
    System.out.println("AB".toLowerCase() == "ab"); // false
    System.out.println("ab".concat("") == "ab");    // true
    System.out.println("ab".substring(0) == "ab");  // true
    System.out.println("ab".toString() == "ab");    // true
    System.out.println("ab".trim() == "ab");        // true