String literals and String Objects
String s1 = "abc"; String s2 = "abc";
Both string s1 and s2 refer to the same string object and value residing in the string literal pool.
String A = new String("abc"); String B = new String("abc");
The two strings A & B are two different string objects, because we used the string constructor to create these two objects. These live in the heap.
Usually you would create string literals over string objects because it gives the compiler a chance to optimize your code.
Immutability of strings.
Since strings are immutable, we have classes like StringBuilder and StringBuffer to make string like objects that are immutable.
Both StringBuilder and StringBuffer provide methods like append(), insert(), delete(), substring(), toString() etc. for string manipulation.
You can look at the String APIs here.
StringBuilder vs. StringBuffer
StringBuffer is thread safe as its methods are synchronized whereas StringBuilder is not.
Given below are three strings.
String a = "hello"; String b = "hello"; String obj = new String("hello");
What would the following equality operators return?
a==obj; // false a==b; // true a.equals(obj); //true a.equals(b); //true
P.S From Java9, strings are now stored as byte arrays instead of char arrays.