In Java, the String class is immutable: every modification creates a new object. The StringBuilder and StringBuffer classes are mutable, used for concatenations within loops and complex transformations.
Key differences:
String: immutable, thread-safe without additional synchronization. Ideal for readable, unchangeable text (e.g., keys, messages).StringBuilder: mutable, not thread-safe, but fast concatenation. Used where strings are modified many times.StringBuffer: mutable, thread-safe (methods are synchronized), but performs worse than StringBuilder.Example comparing speed:
String s = ""; for (int i = 0; i < 10000; i++) { s += i; // creates a new String each time, slow! } // Better to do it like this: StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) { sb.append(i); } String result = sb.toString();
Pitfalls:
String.intern() can cause OutOfMemoryError in PermGen/Metaspace with a large number of unique strings.Question: "Is string concatenation using the "+" operator inside a loop efficient?"
Answer: No, each time a new String object is created, which heavily burdens memory and the GC. For many operations, it is better to use StringBuilder or StringBuffer (if thread safety is required).
Example:
String s = ""; for (int i = 0; i < 1000; i++) { s += i; // VERY inefficient! } // vs StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(i); }
Story
In a banking project, string concatenation using the "+" operator in a large loop slowed down nightly analytics by 15 times. The problem was solved by replacing it with StringBuilder, reducing execution time from 40 minutes to 2.
Story
A young developer made a mistake with threads and used StringBuilder in the same facade object, which was accessed simultaneously by multiple threads. This led to random glitches and incorrect results due to lack of synchronization.
Story
In the project, unique labels were created using String.intern(). As the number of users grew to tens of millions, the JVM started throwing OutOfMemoryError: PermGen space. The problem was solved by abandoning the use of intern() and switching to other caching mechanisms.