-1

I want to change a string literal into all-uppercase one. Here is my code:

    // a and b are the same literal 
    String a = "Test";
    String b = "Test";
    // now I want to change all b's letter 
    // into uppercases, but fail.
    b.toUpperCase();
    System.out.println("a = " + a + ", " + "b = " + b);
    // print: a = Test, b = Test

    String c = "Test1";
    System.out.println("c = " + c + " , c.toUpperCase() = "
                + c.toUpperCase());
    // print: c = Test1 , c.toUpperCase() = TEST1

    // change letters of "Test" literal 
    // into uppercase and success
    System.out.println("Test".toUpperCase());
    // print: TEST

My question is: 1. b can't be changed into uppercase one, but c and "Test" can. Why?

What I know is: 1. a and b reference to the same object in string pool. 2. String is immutable, but it seems not relevant to this question.

weston
  • 54,145
  • 21
  • 145
  • 203
HuangDong.Li
  • 291
  • 1
  • 2
  • 9
  • 5
    What makes you think you've changed anything about `c`? You've displayed the *return value* of `c.toUpperCase()`, that's all. That doesn't change either the value of `c` (a reference) or the data in the string that the value of `c` refers to. – Jon Skeet Mar 05 '16 at 12:09
  • 2
    Where u are holding result of the statement //b.toUpperCase(); –  Mar 05 '16 at 12:12
  • In Java, `String` variables are _immutable_, so once created, you cannot change them. – Mick Mnemonic Mar 05 '16 at 12:14
  • 2
    @MickMnemonic: No, the *variables* aren't immutable (generally), the *objects* are immutable. It's really, *really* important to differentiate between variables and objects. – Jon Skeet Mar 05 '16 at 12:15

7 Answers7

4

Strings are immutable. So for change b:

b = b.toUpperCase(); 

Every time then you do something that changes a String, a new String object is created. So you need change the reference on object.

das-g
  • 9,718
  • 4
  • 38
  • 80
Retardust
  • 294
  • 1
  • 11
2

String is immutable, but it seems not relevant to this question

Actually, it's very relevant to the question

b can't be changed into uppercase one

Because toUpperCase() returns a new string by acting on the invoking string , use

b = b.toUpperCase();

c and "Test" can. Why?

c has not been changed it's result has been added to the string in System.out.println()

svarog
  • 9,477
  • 4
  • 61
  • 77
Ramanlfc
  • 8,283
  • 1
  • 18
  • 24
2

Let's take your code line by line and please read my comments :

// a and b are the same literal 
/* FIRST POINT : 
   Here you assigned two times the same value "Test", 
   BUT IT'S 2 DIFFERENT OBJECTS IN MEMORY */
String a = "Test";
String b = "Test";
// now I want to change all b's letter 
// into uppercases, but fail.
/* SECOND POINT : 
   Here you just apply a function (toUpperCase()) on "b" object. 
   This function returns a string object but 
   YOU ARE NOT DOING ANYTHING WITH IT
   i.e. displaying it or reassigning it to another variable!
   */
b.toUpperCase();
System.out.println("a = " + a + ", " + "b = " + b);
// THAT'S WHY IT STILLS PRINT
// print: a = Test, b = Test

String c = "Test1";
System.out.println("c = " + c + " , c.toUpperCase() = "
            + c.toUpperCase());
/* THIRD POINT : 
   Here you apply a function (toUpperCase()) on "c" object but this time
   YOU ARE REUSING THE RETURN STRING :)
   i.e. you are displaying it!
   */
// print: c = Test1 , c.toUpperCase() = TEST1

// change letters of "Test" literal 
// into uppercase and success
/* LAST POINT : 
   Here you do the same as you did before on "c" object 
   YOU ARE REUSING THE RETURN STRING AGAIN :)
   i.e. you are displaying it!
   */
System.out.println("Test".toUpperCase());
// print: TEST

Last but not least calling toUpperCase()/toLowerCase() functions on string objects will never reassign the object's value. These functions only RETURN a string.

The way to reassign the string value is the usual way :

String a = "Test";
a = a.toUpperCase();

Please note, as many said, that this will create another object in memory "TEST" and assign it to "a" and your old string "Test" will then become a candidate to the garbage collector.

I hope it makes more sense now.

Cheers,

TaiT's
  • 3,138
  • 3
  • 15
  • 26
1

What happens when a string literal is changed?

Nothing. That is the string literal object cannot change, because as you point out you already know, it is immutable. References to it (variables like a,b,c) can be made to reference other strings, but that string instance will not change from "Test".

But to explain your code:

This is the difference between b and c:

b.toUpperCase(); //there's a result from this function you are not using
System.out.println("b = " + b);

System.out.println("c = " + c.toUpperCase()); //you're using the result here.

String is immutable, but it seems not relevant to this question

It is relevant, if you know that it is immutable, it is obvious that b cannot change to upper case and that a new string must be created as a result of toUpperCase and you must therefore use that. However b can be made to reference the new string, and this wont affect a or anything else which still references the old string:

b = b.toUpperCase(); //b now is set to the new upper case string
System.out.println("b = " + b);
weston
  • 54,145
  • 21
  • 145
  • 203
1

My question is: 1. b can't be changed into uppercase one, but c and "Test" can. Why?

My answer is when you print c.toUpperCase(), variable c is not changed at all.

You merely returned the another String which was built to uppercase based on the content of c.

The same applies to String "test" as well.


Even if you do this, you are only pointing c to a new String:

String c = "Test1";
c = c.toUpperCase();  

This is what happened:

//String c = "Test1";
+-------+
|"Test1"| <--- c
+-------+

//c = c.toUpperCase();  
+-------+
|"TEST1"| <--- c
+-------+
+-------+
|"Test1"| <--- waiting to be collected by Garbage collector
+-------+
user3437460
  • 17,253
  • 15
  • 58
  • 106
0

You need to change like this,because strings are immutable

public static void main(String[] args) {
         // a and b are the same literal 
        String a = "Test";
        String b = "Test";

        // now I want to change all b's letter 
        // into uppercases, but fail.
        b= b.toUpperCase();
        System.out.println("a = " + a + ", " + "b = " + b);
        // print: a = Test, b = Test

        String c = "Test1";
       // c=c.toUpperCase();
        System.out.println("c = " + c + " , c.toUpperCase() = "
                    + (c=c.toUpperCase()));
        // print: c = Test1 , c.toUpperCase() = TEST1

        // change letters of "Test" literal 
        // into uppercase and success
        System.out.println("Test".toUpperCase());
        // print: TEST
VVN
  • 1,607
  • 2
  • 16
  • 25
0

I suggest you to look into the Java API. By using toUpperCase you will get a new Object of String. If you want to print out the variable with new text, you should assign the new object to the variable. In case of c, you're printing out the returned "new" content of the object. The variable c will be lower case anymore.

rslkvk
  • 66
  • 5