Objects that are not technically immutable, but whose state will not be modified after publication, are called effectively immutable
Safely Publishedeffectively immutable objects can be used safely by any thread without additional synchronization
String
Strings are immutable in Java
If you pass strings around, this will not change the string on the memory
Java has special area in heap memory called String Pool
Before creating a new String, Java checks whether the exact value exists in the string pool
You can force java to create string outside of String pool by using new operator
public class Test { public static void main(String[] args) { String s1 = "hello"; String s2 = "hello"; String s3 = new String("hello"); System.out.println(s1 == s2); // true System.out.println(s1 == s3); // false }}
Hence, we should not use == to compare strings
Why use StringBuilder?
Since String is immutable, each method you invoke on a String creates a new object and returns it.
Hence, each append using += causes new string objects to be created
StringBuilder is mutable. When you call append() it alters the internal byte[] array, rather than creating a new string object.
For optimization reasons, byte[] array is used to store string instead of char[] array
Java compiler also try to optimize wherever possible. For example it will convert expression: A + B + C to StringBuilder(A).append(B).append(C).toString() to make it efficient at the compile time itself
class Immutable { private final int value; public Immutable(int value) { this.value = value; } public int getValue() { return value; }}class Mutable extends Immutable { private int realValue; public Mutable(int value) { super(value); realValue = value; } public int getValue() { return realValue; } public void setValue(int newValue) { realValue = newValue; }}class Printer { public static void printVal(Immutable immObj) { // assume that immObj is immutable System.out.println(immObj.getValue()); }}public class Test { public static void main(String[] args) { Mutable obj = new Mutable(4); Printer.printVal(obj); // 4 // assuming it is changed by another thread obj.setValue(8); Printer.printVal(obj); // 8 }}