-2

What I read is that the function toUpperCase actually returns a new String object, and I did check the code inside Java.lang.String and it really creates a new string.

this is a code from Java.lang.string class, method toUpperCase

        int resultOffset = 0;
        char[] result = new char[len]; /* may grow */

This is my code now:

    String s1 = new String("THAT");
    String s2 = s1;
    System.out.println(s1 == s2); // true
    s1 = s1.toUpperCase();
    System.out.println(s1 == s2); // true, how is that?

The first (s1 == s2) returns true and that is obvious. But how can the second one returns true as well? after the toUpperCase method, shouldn't s1 becomes a new String? while s2 still points to the old s1. Thus, the memory location for both of them should be not the same, and as == compares the memory locations. the result should be false.

I know that I am wrong in some point of my argument, but where is that point?

Marco Dinatsoli
  • 10,322
  • 37
  • 139
  • 253
  • _after the toUpperCase method, shouldn't s1 becomes a new String_ Why do you think so? – Sotirios Delimanolis Oct 28 '15 at 01:05
  • @SotiriosDelimanolis because the toUpperCase method returns a new String, that is why i showed u the code from String class method toUpperCase – Marco Dinatsoli Oct 28 '15 at 01:06
  • Why do you think it does? – Sotirios Delimanolis Oct 28 '15 at 01:06
  • @SotiriosDelimanolis I think it creates a new object that references to a memory location which contains the upper value of that string `THAT` – Marco Dinatsoli Oct 28 '15 at 01:07
  • Why do you think it returns a **new** instance instead of returning the **same** (the one it was invoked on) instance? – Sotirios Delimanolis Oct 28 '15 at 01:08
  • @SotiriosDelimanolis because I am having a course in Coursera java class, and that is what the teacher said, and then i checked the code and it actually creates a new String – Marco Dinatsoli Oct 28 '15 at 01:08
  • @CrakC I know, but that is just the value, while `==` compare the reference, not the value – Marco Dinatsoli Oct 28 '15 at 01:09
  • In this case, because the `String` is already in uppercase, it returns the `this`, the same `String` – MadProgrammer Oct 28 '15 at 01:09
  • here your question have answer http://stackoverflow.com/questions/767372/java-string-equals-versus – JAVAC Oct 28 '15 at 01:09
  • Obviously not, if your code is behaving this way. – Sotirios Delimanolis Oct 28 '15 at 01:09
  • @MadProgrammer that is an interesting idea, i though that in the beginning (the same case as substring), but then i read the code and in the code (you can check) they are creating a new char array regardless of checking if the string is already upper case – Marco Dinatsoli Oct 28 '15 at 01:11
  • 1
    As stated in the linked post: _`toLowerCase()` would have recognized it, and returned the original string_. The same logic applies to `toUpperCase`, it returns the same string if there are no changes to be made. This is not explicitly stated, so don't depend on it. – Sotirios Delimanolis Oct 28 '15 at 01:13
  • @MarcoDinatsoli I ran the `public String toUpperCase(Locale locale) {` method, they do a check to see if any of the characters need to be changed, if they don't it uses `return this` (line 2733 of the `String` class (Java 8)), otherwise it goes ahead and creates a new char array and generates a new `String`. You could also print the `hashcode` of both `s1` and `s2`, in your above example, they are the same – MadProgrammer Oct 28 '15 at 01:14
  • @MadProgrammer you are right, now i see the `break scan` statement in the method. Then it is exactly the same situation as string . substring where the check if the beginning and the end are the same, they return the original string, otherwise, (after java 7) they return a new string, not a view of the old string. – Marco Dinatsoli Oct 28 '15 at 01:16
  • @SotiriosDelimanolis really duplicated? ?? ? ?? ? !!!! !!! !! do you really see that question talks about to upper case? – Marco Dinatsoli Oct 28 '15 at 01:17
  • @SotiriosDelimanolis oh yes it is duplicated sorry – Marco Dinatsoli Oct 28 '15 at 01:18

2 Answers2

2

In the JDK String.toUpperCase(Locale locale) method body if the string is all Uppercase it returns the same String

        /* Now check if there are any characters that need to be changed. */
    scan: {
        for (firstLower = 0 ; firstLower < len; ) {
            int c = (int)value[firstLower];
            int srcCount;
            if ((c >= Character.MIN_HIGH_SURROGATE)
                    && (c <= Character.MAX_HIGH_SURROGATE)) {
                c = codePointAt(firstLower);
                srcCount = Character.charCount(c);
            } else {
                srcCount = 1;
            }
            int upperCaseChar = Character.toUpperCaseEx(c);
            if ((upperCaseChar == Character.ERROR)
                    || (c != upperCaseChar)) {
                break scan;
            }
            firstLower += srcCount;
        }
        return this;
    }
John
  • 315
  • 2
  • 7
  • Oh god, i didn't see the `break scan` statement. That is the reason. Then if all the chars are already in the upper case mode, the code won't continue and the method will return **this**. (voted) – Marco Dinatsoli Oct 28 '15 at 01:14
0

Because s1 is already uppercase. The JVM returns the same internd String. You can explicitly make it a new one. Like,

String s1 = "THAT"; // <-- no need for new String here.
String s2 = new String(s1);
System.out.println(s1 == s2);

or change s1 to lowercase first. Something like,

String s1 = "that";
String s2 = s1.toUpperCase();
System.out.println(s1 == s2);

In both cases, you'd get false.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • This is another think, my question is why the result is true since the s1 and s2 reference now to different memory location. you gave me example about another issue – Marco Dinatsoli Oct 28 '15 at 01:10