← Core Java | Notes | Home
-
String Literal — SCP,
== comparison
-
String Object —
new keyword, heap memory
-
String Immutability — thread safety, SCP, security
-
StringBuilder & StringBuffer — mutable, synchronized, thread-safe
← Core Java | Notes
Type of a String Object which is mostly used. Declared directly using String keyword and actual string value in double quotes without using new keyword.
String s1 = "Hello";
String s2 = "Hello";
s1 == s2 // true
-
String literal object is stored in String Constant Pool insie heap memory.
-
If String object of same value already exists in the String Constant Pool JVM reuses it and hence it is memory efficient.
-
== returns true if two String literals have same value (ie same string) because both references to same object in memory.
String object created using new keyword.
String s1 = new String("Hello");
String s2 = new String("Hello");
s1 == s2 // false
-
It is store in heap memory outside String Constant Pool.
-
New Object is created everytime
-
Once a String literal or String Object is created, its value cannot be changed.
-
Any modifications (like concat(), replace(), etc) creates a new String Object instead of modifying the existing one.
String s1 = "Hello";
s1.concat(" World");
System.out.println(s1) // Hello
because s1 reference to "Hello". concat() creates a new String Object, but the returned object is not assigned back to s1.
Reasons why String is immutable:
-
Thread safety
-
Memory optimization through String Pool reuse
-
Security (important for class loading, URLs, file paths, etc)
-
Immutability is a foundation of functional programming
-
They are used to modify the same object in memory instead of creating new objects.
-
They use internal character array that grows dynamically when needed.
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb) // Hello World
append() modifies the same object instead of creating new one.
-
Not thread-safe
-
Faster because there is no synchronization overhead.
-
Used in single-threaded environment where performance is important.
-
Thread-safe
-
Slighty slower than StringBuilder because methods are synchronized
-
Used in multithreaded environment
-
Most methods in StringBuffer are synchronized.
-
Only one thread can execute synchronized methods on the same object at a time.
-
This prevents multiple threads from modifying the internal character array simultaneously.
public synchronized StringBuffer append(String str)
Synchronization ensures thread safety but adds performance overhead.
StringBuilder was introduced in Java 5 as a faster alternative to StringBuffer when thread safety is not required.
String Constant Pool (SCP) is a special memory in heap to store String Literals.
So when a new String Literal is is created, jvm checks SCP first :
-
If the same value already exists in the pool, the existing String Object is reused, and the new reference variable points to that existing object.
-
Otherwise a new string object is created in the pool.
This reduces unnecessary object creation, saves memory, and improves performance because multiple references can point to the same immutable String Object.
-
String is immutable once created cannot be changed. If modified, new object is created.
-
StringBuffer and StringBuiler are used to create mutable string objects. If modified, the same object is updated instead of creating a new one.
-
StringBuilder is not thread-safe and is faster compared to StringBuffer because it does not have synchronization.
-
StringBuffer is thread-safe is slighty slower than StringBuilder because its methods are synchronized. It is mainly used in multithreaded environment.
Strings are immutable for security, thread-safety and performance reasons.
-
Immutability prevents modifications of sentitive data like passwords, file paths, database URLs, etc.
-
Since strings cannot be changed, they can be safely shared across multiple threads without synchronization.
-
Immutability allows the JVM to use the String Constant Pool (SCP), where string literals with the same value are reused, resulting in better memory efficiency and performance.
String Literal :
String Object :
Note :
equals() compares content, whereas == compares references.
s1.equals(s2) // true .. even when == is false.
-
When frequent modifications to a string are required, since StringBuffer is mutable.
-
When same data is shared aross multiple threads concurrently in multithreaded environment.
-
When thread-safety is required, because the method of StringBuffer are synchronized.
What Happens Here?
String s1 = "hello";
s1.concat(" world");
System.out.println(s1); // hello
-
String is immutable, so concat() does not modify the existing object.
-
A new String object "hello world" is created in memory.
-
Since the returned object is not assigned to any variable, it becomes eligible for garbage collection.
-
s1 still points to "hello".
-
Immutable objects are safer because their state cannot be accidentally changed.
-
String, Integer, and LocalDate are common immutable classes in Java.
-
Make the class final so it cannot be inherited.
-
Make all fields private and final.
-
Initialize fields using a constructor.
-
Do not provide setter methods.
-
For mutable fields like list, return defensive copies to prevent external modification.
final class Employee{
private final String name;
private final List<String> skills;
public Employee(String name, List<String> skills){
this.name = name;
this.skills = List.copyOf(skills);
}
// setters
public String getName() {
return name;
}
public List<String> getSkills() {
return List.copyOf(skills);
}
}
← Core Java | Notes | Home