s1 == s2; // true, but different references so had to return false
No, both are referring same String literal object "123"
in String literal pool. Hence returned true, when you checked with ==
If you use String s = "Some"
to create object, the object is referred from String Constant Pool.
If you use the new operator to create the object, then in heap String objects will be created.