String immutability in Java
Methods return new Strings; the original never changes.
name.toUpperCase(), print name... and it's still lowercase. Did Java just ignore you? Not at all — it answered, but nobody was listening.Text carved in stone
Think of a String as words carved in stone. You can read them, copy them, carve a new stone — but you can never re-chisel the old one. In Java terms: once a String is created, its characters never change. We call that *immutable*.
Methods hand you a NEW String
toUpperCase, replace, trim, substring... none of them touch the original. Each one builds a brand-new String and returns it. If you want to keep the result, you must catch it in a variable.
String s = "hello";
String up = s.toUpperCase();
System.out.println(s); // hello
System.out.println(up); // HELLOYour turn
What does this print?
String city = "paris";
city.replace('p', 'P');
System.out.println(city);ParisparisPARIS
Show the answer
paris. replace built a new String "Paris" — and then it was thrown away, because nothing stored it. city still points at the untouched original.
The lost result
A line like name.trim(); on its own compiles fine and does nothing useful: the trimmed copy is created and immediately discarded. The fix is to reassign: name = name.trim(); — now name points at the new, trimmed String.
String name = " Ada ";
name.trim(); // result lost!
name = name.trim(); // kept: "Ada"Moving the arrow
Two variables start out pointing at the same String. What prints?
String a = "cat";
String b = a;
a = a + "s";
System.out.println(b + " " + a);cats catscat catscat cat
Show the answer
cat cats. a + "s" builds a new String and only a is moved to it. b still points to the original "cat", which nobody can ever change.
Why design it this way?
Java's creators could have made Strings editable. Why didn't they?
Think about it, then reveal the answer
Because a String nobody can change is safe to share. The JVM can reuse one copy of a literal everywhere (the String pool), cache its hash code for fast HashMap lookups, and pass it between threads without locks. If Strings were mutable, changing one shared literal would silently change it everywhere.
In real projects
Strings are the most common HashMap keys and they carry file paths, URLs and user names through security checks. Immutability guarantees that a value checked once can't be swapped behind your back afterwards. And the classic beginner bug — s.trim(); without assignment — is flagged by IntelliJ as "result of method call ignored".
Key takeaways
- String methods return a new String; the original stays the same
- Calling s.trim(); on its own line throws the result away
- Reassigning s = s.trim() points s at the new String
- Immutability makes Strings safe to share between variables and threads
💡 A String is like a printed page: to 'edit' it you print a new page; the old one stays as it was.
A String remembers its own hash code: the first hashCode() call computes it and stores it in a private field, so later calls are instant. That's only safe because the text can never change.
Practice questions
What does this print?
String s = "java";
s.toUpperCase();
System.out.println(s);- JAVA
- java
- Java
Check your answer
java. The uppercase copy was returned but never stored, so s still refers to "java".
What does this print?
String s = "hi";
String t = s;
s = s + "!";
System.out.println(t);
System.out.println(s);- hi! hi!
- hi hi!
- hi hi
- hi! hi
Check your answer
hi hi!. s + "!" creates a new String and only s is moved to it. t still points to the untouched original "hi".