hi krish..... there is no bug in your code System.out.println("s3==s4"+s3==s4);//lineX in this case first s3 gets concanated to your "s3==s4" and then there is comparision betn "s3==s4apple" == s4 first second so output false
Println() always calls the toString() method on Object and the returned toString() String argument will not be placed String pool but will be stored as a normal attribute in local method stack, or treated as argument to method println().
Here the toString() method on both s3 & s4 will be called and 2 String objects in local stack will be created, so the == will give false, because, they are pointing to different memory locations.
This is a wonderfully subtle issue, and only Amod Gole picked up on it; neither Ulf nor Srinivas spoke to it.
The reason that only 'false' is printed, and not 's3 == s4 false' is that the expression
"s3 == s4" + s3 == s4
is not interpreted as
"s3 == s4" + (s3 == s4)
but rather as
("s3 == s4" + s3) == s4
and, given that, it should be obvious why just 'false' is printed.
Note that much of what Srinivas says about Strings and pools and stacks and locals and so on and so on wouldn't be relevant (or quite correct) even if this was a question about equals() vs. == -- but it's not.