我有以下代码
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时,为什么我会“假”?
答案 0 :(得分:5)
因为s1.trim()
将返回一个新实例。字符串是不可变的,因此每次在字符串上应用函数时,都会返回一个新实例,并且您正在使用==
来比较实例相等性
编辑正如Chris Hayes和R.J。
所建议的那样 trim
很聪明,如果没有要修剪的空白,则返回this
。所以在第二种情况下你有'abc'空格,所以在这种情况下它不会返回this
而是一个新的字符串实例。
答案 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上找到。