public class Test { public static void main(String[] args) {
String s1="Abc"; 
String s2="abc"; 
String s3=s1.toLowerCase(); 
String s4=s2.toLowerCase(); 

System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s1==s4);
System.out.println(s2==s3);
System.out.println(s2==s4);
System.out.println(s3==s4);
}
}
运行结果 :
false
false
false
false
true
false
求原因????s3,s4是运行时确定还是编译时?

解决方案 »

  1.   

    s2.toLowerCase(); 
    这个方法在处理之前会先分析s2所指的串,如果本身就全是小写,那么直接返回这个对象,得到的仍然是"abc",如果其中有大写的,则创建一个新的串,返回.
      

  2.   

    可以自己去看toLowerCase方法的源代码
      

  3.   

    JDK 源代码:
    public String toLowerCase() {
            return toLowerCase(Locale.getDefault());
        }
    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: {
                int c;
        for (firstUpper = 0 ;
                        firstUpper < count ; 
                        firstUpper += Character.charCount(c)) {
    c = codePointAt(firstUpper);
    if (c != Character.toLowerCase(c)) {
                        break scan;
                    }
        }
        return this;//注意这里,如果传入的字符串本身全是小写的话,那么就返回自己,而不是新创建一个String对象,toUpperCase也是一样的,所以s2==s4返回true
    }        char[]  result = new char[count];
    int     resultOffset = 0;  /* result grows or shrinks, 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().intern();
    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 = codePointAt(i);
                srcCount = Character.charCount(srcChar);
                if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
                    lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
                } else {
                    lowerChar = Character.toLowerCase(srcChar);
                }
                if ((lowerChar == Character.ERROR) ||
                        Character.isSupplementaryCodePoint(lowerChar)) {
                    if (lowerChar == Character.ERROR) {
                        lowerCharArray =
                            ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
                    } else {
                        lowerCharArray = Character.toChars(lowerChar);
                    }
                    /* Grow/Shrink result. */
                    int mapLen = lowerCharArray.length;
                    char[] result2 = new char[result.length + mapLen - srcCount];
                    System.arraycopy(result, 0, result2, 0,
                        i + resultOffset);
                    for (int x=0; x<mapLen; ++x) {
                        result2[i+resultOffset+x] = lowerCharArray[x];
                    }
                    resultOffset += (mapLen - srcCount);
                    result = result2;
                } else {
                    result[i+resultOffset] = (char)lowerChar;
                }
            }
            return new String(0, result.length, result);
        }
      

  4.   

    我的理解是:
    s2是存储在String pool中没错吧?然后s4在运行时才确定,好像不是放在String pool 中,好像要用个intern才转到这里来的,请帮我指正??谢谢
      

  5.   

    楼主,这个sun公司得考试题已经不知道提起多少次了你去jdk看看 那个toLowerCase和 toUperCase源码吧字符串经过这个函数之后内存地址是不变得。也许你想问为什么,那你去问java开发人员可以
      

  6.   

    跟常量池有关
    toLowerCase判断了不需要改变,所以仍然使用原字符串常量
    如果toLowerCase不判断,那性能也太低了.
    我觉得是运行时决定的,虽然现在的编译器很强了,但是不会处理toLowerCase这个过程
    字符串相加这种简单的过程编译时会处理的.
      

  7.   

    s4就相当于经过一些列的处理
    .....
    最后
    s4=s2;
    其实前面如何处理已经不重要了.
      

  8.   

    楼主应该弄清字符串在java中的特性首先字符串是存储在数据段中
    然后字符串有不可变特性字符串只要改变(不管是怎么变,反正就是如果和原串不一样,就会在数据段中产生一个新串)
    知道这点就好办了首先s1--->"Abc", s2--->"abc"
    数据段中的两个不同的位置System.out.println(s1==s2); 
    位置不同, false
    System.out.println(s1==s3); 
    s3=s1.toLowerCase();改变了s1的值产生新串"abc",s3--->"abc"这个"abc"的位置和前两个都不一样,false
    System.out.println(s1==s4); 
    s4=s2.toLowerCase();s2值没有改变,所以没有产生新串,s4和s2指向的是同一位置,false 
    System.out.println(s2==s3); 
    由上可知s2与s3位置不同,false
    System.out.println(s2==s4); 
    由前面分析,s2与s4指向位置相同,true
    System.out.println(s3==s4); 
    s3,s4指向位置不同,false
      

  9.   

    嗯。确实是这样,字符串和普通的java对象是一样的,s1==s2其实比较的就是字符串的地址是否相同。