为什么“==”有时可以使用String.trim?

时间:2013-12-18 05:40:14

标签: java string

我有以下代码

public static void main(String... args) {

    String s = "abc";
    System.out.println(s.hashCode());
    String s1 = " abc ";
    System.out.println(s1.hashCode());
    String s2 = s.trim();
    System.out.println(s2.hashCode());
    String s3 = s1.trim();
    System.out.println(s3.hashCode());
    System.out.println();
    System.out.println(s == s1);
    System.out.println(s == s2);
    System.out.println(s == s3);
}

OP:

96354
32539678
96354
96354

false   -- Correct
true    -- This means s and s2 are references to the same String object "abc" .
false   -- s3=s1.trim()... which means s3="abc" yet s==s3 fails.. If the above conditon were to be considered (s==s2 is true..) , this should also be true.. 

当我检查s == s3时,为什么我会“假”?

5 个答案:

答案 0 :(得分:5)

因为s1.trim()将返回一个新实例。字符串是不可变的,因此每次在字符串上应用函数时,都会返回一个新实例,并且您正在使用==来比较实例相等性

编辑正如Chris Hayes和R.J。

所建议的那样

trim很聪明,如果没有要修剪的空白,则返回this。所以在第二种情况下你有'abc'空格,所以在这种情况下它不会返回this而是一个新的字符串实例。

trim method

的源代码

答案 1 :(得分:2)

public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */

    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    while ((st < len) && (val[len - 1] <= ' ')) {
        len--;
    }
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

正如您在案例中看到的那样(System.out.println(s == s2);this将返回指向相同的引用,这就是您实现的原因。

答案 2 :(得分:2)

如果您查看String.trim,您会看到它最终会调用String.substring,如果字符串实际被修剪,则会new String(...)返回==。这就是{{1}}失败的原因。

答案 3 :(得分:1)

请参阅文档 - http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim() -

A copy of this string with leading and trailing white space removed, or this string if it has no leading or trailing white space.

当字符串保持不变时,它返回给定的字符串。

答案 4 :(得分:1)

java.lang.String.trim()的Java 7源代码(来自已安装的JDK)是:

public String trim() {
    int len = value.length;
    int st = 0;
    char[] val = value;    /* avoid getfield opcode */

    while ((st < len) && (val[st] <= ' ')) {
        st++;
    }
    while ((st < len) && (val[len - 1] <= ' ')) {
        len--;
    }
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}

return语句指出如果被修剪的String没有变化,则返回,因此s == s2:

String s = "abc";
String s2 = s.trim();
System.out.println(s == s2); // is true

当需要修剪要修剪的String时,将调用java.lang.String.substring()。 Java 7中substring()的源代码是:

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > value.length) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    int subLen = endIndex - beginIndex;
    if (subLen < 0) {
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
            : new String(value, beginIndex, subLen);
}

当要修剪的String必须被修剪时,substring()返回一个新的String:

new String(value, beginIndex, subLen)

这就是为什么s!= s3:

String s = "abc";
String s1 = " abc ";
String s3 = s1.trim();
System.out.println(s == s3); // is false

此答案的源代码可在GitHub here上找到。