Its because s3 and s4 are two different reference variables. So, even though their contents are the same, when you use == operator, it returns false.
Whereas, in the second println statement, the String constant pool comes into picture. If the JVM finds the same string in the pool, instead of creating a new object, it will make the new reference point to the already existing String.
So, since "Hai" is already present in the pool (which was created through String a="Hai"), JVM just points the reference b to it, and hence it returns true when comparing a and b using == operator.
s3 and s4 are reffrering two different objects.== checks wheather bothe references two same object or not.If you use equals() method then the result will be true. And in a==b it returns true as ure creating String without new operator. So at the the time of creating object referenced by a stored in String pool and b references to the same object.If you use new operator for creating String then it will return false.