This week's book giveaways are in the iOS and Features new in Java 8 forums. We're giving away four copies each of Barcodes with iOS: Bringing together the digital and physical worlds and Core Java for the Impatient and have the authors on-line! See this thread and this one for details.
First of all, the == operator compares object references and not the contents of the objects themselves. So, == will only return true if the operands on both sides of it refer to the exact same object. If you have two separate String objects it will return false, even if the String objects contain the same characters. If you want to compare two String objects to see if they contain the same characters, use the equals() method:
Second, string literals are stored in a pool by Java. If you use the same string literal twice (or more times), the string is stored only once in the program. Because of this, s1 and s2 refer to the same String object in your program, so s1 == s2 is true.
With s3, you are explicitly creating a new String object, which is initialized with the contents of the literal "abc". Because you explicitly create a new String object, it is a different object than the one in the pool that s1 and s2 point to, so s1 == s3 is false.
By the way, you should never use new String("...") (the String constructor with a string literal as an argument) in a serious Java program, because it isn't necessary and only adds overhead (you create an extra String object without any benefits).
The literal string "abc" is 'interned' means it is added to an internal pool of strings maintained by the JVM. So when you compared s1 == s2 the comparison took place between same object references and hence the result was 'true'. On the other hand when you create a String object using 'new', the JVM does not check the internal pool but creates a new object. This is the reason the result of s1 == s3 came as 'false'.
1) The == operator asks if two variables refer to the same object -- i.e., they point to the same physical block of memory in the computer.
2) The equals() method, on the other hand, asks if two objects are "the same" in some way that makes sense for a particular class. For String, it means the two Strings contain the same characters in the same order.
3) Finally (and this is slightly oversimplifying, but indulge me, Tony) all identical String literals (Strings that appear in a program between double quotes) refer to the same String object; in other words, if the sequence "abc" appears three times in a program, then all three copies refer to the same physical String object in the computer's memory.
SO now we can look at your program and understand the output. s1 and s2 refer to the same String object, so "==" says true; s3 is another object altogether, since you created it with "new". It contains the same characters, in the same order, but it's a different chunk of memory.
Now, if you replace "==" with equals() -- i.e., if (s1.equals(3)) -- then all the answers would be true, since all the Strings have the same characters in the same order.
THe moral of this story is that you should never use == to compare Strings: always use the equals() function. As a general rule, you should use the equals() function to compare objects unless you have some specific reason to use ==; some specific reason why you're testing if two things are the same object, rather than just whether they're alike.