Whenever you declare a String like String s = "hello" the JVM puts that object in the pool of Strings maintained by the String class, unless a matching String is already there, in which case it points the new String object to that place in memory.
Whenever you use the '==' operator on objects, you are comparing references. So, the following code will return true:
Now, whenever you use the + operator on two Strings, a new String object, and hence a new reference, is always returned, so your first 3 checks all returned false.
When you used the 'intern()' method, however, you forced the JVM to compare your new String to all the Strings in the String pool (mentioned earlier), and return a reference to any one that it found a match for. So, it found that "helloworld" was already there, and returned a reference to it, rather than creating an entirely new object. Of course, "helloworld" == "helloworld".