Why Strings Are Immutable
Understand string immutability.
Why Strings Are Immutable is a free Java Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Strings Cannot Change
In Java a String is immutable: once created, its characters can never change. Any method that seems to modify a string actually returns a brand new string.
Methods Return New Strings
toUpperCase(), replace(), and friends do not alter the original. They produce a new String and leave the original untouched.
public class Main {
public static void main(String[] args) {
String original = "hello";
String upper = original.toUpperCase();
System.out.println("original: " + original);
System.out.println("upper: " + upper);
}
}Reassignment Is Not Mutation
When you write s = s + "!", the variable now points to a new string. The old string object is unchanged and may be garbage collected.
public class Main {
public static void main(String[] args) {
String s = "hi";
String firstRef = s;
s = s + "!";
System.out.println("s: " + s);
System.out.println("firstRef: " + firstRef);
}
}Why Immutability?
Immutability brings real benefits:
- Thread safety: strings can be shared without locks
- Caching: hash codes and pool entries stay valid
- Security: a string passed to a method cannot be changed underneath you
The String Pool
Identical string literals can share one object in the string pool. This is only safe because strings never change. Here two literals refer to the same pooled object.
public class Main {
public static void main(String[] args) {
String a = "java";
String b = "java";
System.out.println(a == b);
System.out.println(a.equals(b));
}
}new String Breaks Pooling
Using new String(...) forces a separate object, so reference equality differs even though contents match. Always compare contents with equals.
public class Main {
public static void main(String[] args) {
String a = "java";
String b = new String("java");
System.out.println("== : " + (a == b));
System.out.println("equals: " + a.equals(b));
}
}The Concatenation Cost
Each + on strings creates a new object. Doing this in a loop allocates many short-lived strings, which wastes time and memory.
public class Main {
public static void main(String[] args) {
String result = "";
for (int i = 1; i <= 5; i++) {
result = result + i;
}
System.out.println(result);
}
}Quadratic Growth
Because each concatenation copies all previous characters, building a long string with + in a loop scales poorly (roughly O(n squared)). This is the core performance problem.
public class Main {
public static void main(String[] args) {
String s = "";
for (int i = 0; i < 1000; i++) {
s += "x";
}
System.out.println("Length: " + s.length());
}
}Immutable Values Are Predictable
Passing a string to a method is safe: the method cannot change your copy. Here the method builds a new string and the caller's value is intact.
public class Main {
static void shout(String s) {
s = s + "!!!";
System.out.println("inside: " + s);
}
public static void main(String[] args) {
String msg = "hello";
shout(msg);
System.out.println("outside: " + msg);
}
}The Solution Preview
When you need to build strings efficiently, Java provides StringBuilder, a mutable companion class. It changes in place instead of allocating new objects each time.
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 5; i++) {
sb.append(i);
}
System.out.println(sb.toString());
}
}Comparing the Two Approaches
For a few concatenations, + is perfectly fine and readable. For many in a loop, prefer StringBuilder. Choose based on how much building you do.
public class Main {
public static void main(String[] args) {
String simple = "a" + "b" + "c";
StringBuilder sb = new StringBuilder("a");
sb.append("b").append("c");
System.out.println(simple);
System.out.println(sb);
}
}Quick Check
What actually happens when you call s.toUpperCase() on a String?
Recap
You learned why strings are immutable:
- A
String's contents never change - Methods return new strings
- Immutability enables thread safety, pooling, and security
- Concatenating with
+in loops scales poorly StringBuilderis the mutable solution
Frequently asked questions
Is the “Why Strings Are Immutable” lesson free?
Yes — the full text of “Why Strings Are Immutable” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Why Strings Are Immutable”?
Understand string immutability. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Why Strings Are Immutable” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Why Strings Are Immutable
- Building Strings with StringBuilder
- StringBuilder Methods
- StringBuilder vs StringBuffer