Brendon Cheung
Brendon Cheung

Reputation: 1035

String pool in java, compile time vs run time string evaluations

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

Answers (3)

Fullstack Guy
Fullstack Guy

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

user1717259
user1717259

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 trimed.

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

Jac Robertson
Jac Robertson

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

Related Questions