Reputation: 1035
I am study on getting my OCA exam and stuck on this java string pool concept.
Consider the follow:
public static void main(String[] args) {
String s1 = "Hello"; // since s1 and s2 are the same literal at compile-time, therefore they will be string pooled
String s2 = "Hello";
String s3 = "Hello".trim();
StringBuilder sb1 = new StringBuilder("Hello"); // although they are the same string, == only checks for object equality
StringBuilder sb2 = new StringBuilder("Hello");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // true
System.out.println(sb1 == sb2); // false
}
s1
and s2
are identical in string AND also identical in object because since it is the same string literal, the JVM will string pool s1
and s2
at compile-time.
Now, s3
is computed at run-time and therefore should return a new string. Therefore, s1 == s3
should be false, but that is not the case. Why?
One theory I have is the trim()
method checks to see if there are any white space to remove to begin with, if it doesn't, then simple return itself. That would explain why s1 == s3
, but I'm not sure.
Thanks
Upvotes: 1
Views: 119
Reputation: 16908
That is correct if you look at the source of the trim()
method, you would see that after removing the whitespaces the substring(start, end)
is invoked. Else if there were no whitespaces then the same instance this
is returned.
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;
}
Here st
is the start index after removing the whitespaces and len
is the new length.
Now if there was any whitespace like before or after the string:
String s1 = "hello "; //<-- whietspace at the end
System.out.println(s1.trim() == "hello");
The output is false
as the substring()
was invoked by the trim()
method. The substring returns a new String instance if the beginIndex
and endIndex
is not the same:
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
So after removing the whitespaces if any, the beginIndex
and endIndex
would obviously change and a new String()
instance will be returned.
Upvotes: 2
Reputation: 2863
Here's the source code for trim(). If there's no whitespace to remove, then it returns this
. So it's the same reference you trim
ed.
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;
}
Upvotes: 1
Reputation: 31
You are correct. If the trim() method doesn't change the value, then the original instance will be returned. If all the "Hello" was changed to " Hello", s3 would not be equal to s1 as trim() would remove the whitespace and return a new string instance.
Upvotes: 3